[PATCH] D152764: [clang-tidy] Reserved-identifier: Improved AllowedIdentifiers option to support regular expressions

2023-06-12 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Thanks for the patch. This seems like it'll make the check much more useful.




Comment at: clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp:48
+  Options.get("AllowedIdentifiers", ""))) {
+  for (const auto  : AllowedIdentifiers) {
+if (!llvm::Regex(Identifier).isValid())

Nit: we should `AllowedIdentifiersRegex.reserve(AllowedIdentifiers.size())` 
before the loop.



Comment at: clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h:34
   const std::vector AllowedIdentifiers;
+  llvm::SmallVector AllowedIdentifiersRegex;
 

I understand that we need to keep the `AllowedIdentifiers` member around for 
use in `storeOptions`. To avoid confusion, it might make sense to change its 
name to be the "less default" name (something like `AllowedIdentifiersRaw`), 
and give the vector of regexes the more intuitive name `AllowedIdentifiers`. 
That would further avoid confusion since `getFailureInfoImpl` in the .cpp 
currently refers to the vector of regexes using the name `AllowedIdentifiers`.

Also, this should probably be `const` for consistency. The loop in the 
constructor body should arguably be moved into a helper function anyway, so 
this member can be initialized in the constructor initializer list.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152764/new/

https://reviews.llvm.org/D152764

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


[PATCH] D116824: [clang-tidy] Fix RenamerClangTidyChecks suggesting invalid macro identifiers

2022-01-10 Thread Logan Smith via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG988c3f5f9692: [clang-tidy] Fix RenamerClangTidyChecks 
suggesting invalid macro identifiers (authored by logan-5).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116824/new/

https://reviews.llvm.org/D116824

Files:
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -171,6 +171,11 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: declaration uses identifier '_', 
which is reserved in the global namespace; cannot be fixed automatically 
[bugprone-reserved-identifier]
 // CHECK-FIXES: {{^}}int _;{{$}}
 
+// https://github.com/llvm/llvm-project/issues/52895
+#define _5_kmph_rpm 459
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses identifier 
'_5_kmph_rpm', which is reserved in the global namespace; cannot be fixed 
automatically [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define _5_kmph_rpm 459{{$}}
+
 // these should pass
 #define MACRO(m) int m = 0
 
Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
===
--- clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -486,6 +486,9 @@
   NamingCheckFailure  = NamingCheckFailures[ID];
   SourceRange Range(MacroNameTok.getLocation(), MacroNameTok.getEndLoc());
 
+  if (!isValidAsciiIdentifier(Info.Fixup))
+Failure.FixStatus = ShouldFixStatus::FixInvalidIdentifier;
+
   Failure.Info = std::move(Info);
   addUsage(ID, Range);
 }


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -171,6 +171,11 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: declaration uses identifier '_', which is reserved in the global namespace; cannot be fixed automatically [bugprone-reserved-identifier]
 // CHECK-FIXES: {{^}}int _;{{$}}
 
+// https://github.com/llvm/llvm-project/issues/52895
+#define _5_kmph_rpm 459
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses identifier '_5_kmph_rpm', which is reserved in the global namespace; cannot be fixed automatically [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define _5_kmph_rpm 459{{$}}
+
 // these should pass
 #define MACRO(m) int m = 0
 
Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
===
--- clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -486,6 +486,9 @@
   NamingCheckFailure  = NamingCheckFailures[ID];
   SourceRange Range(MacroNameTok.getLocation(), MacroNameTok.getEndLoc());
 
+  if (!isValidAsciiIdentifier(Info.Fixup))
+Failure.FixStatus = ShouldFixStatus::FixInvalidIdentifier;
+
   Failure.Info = std::move(Info);
   addUsage(ID, Range);
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116824: [clang-tidy] Fix RenamerClangTidyChecks suggesting invalid macro identifiers

2022-01-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added reviewers: njames93, aaron.ballman.
logan-5 added a project: clang-tools-extra.
Herald added subscribers: carlosgalvezp, xazax.hun.
logan-5 requested review of this revision.
Herald added a subscriber: cfe-commits.

This behavior was fixed for regular identifiers in 
9f3edc323a88c1a179a0a5a9dc9a87a2964c0d48 
, but the 
same fix was not applied to macro fixits.

This addresses https://github.com/llvm/llvm-project/issues/52895.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116824

Files:
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -171,6 +171,11 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: declaration uses identifier '_', 
which is reserved in the global namespace; cannot be fixed automatically 
[bugprone-reserved-identifier]
 // CHECK-FIXES: {{^}}int _;{{$}}
 
+// https://github.com/llvm/llvm-project/issues/52895
+#define _5_kmph_rpm 459
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses identifier 
'_5_kmph_rpm', which is reserved in the global namespace; cannot be fixed 
automatically [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define _5_kmph_rpm 459{{$}}
+
 // these should pass
 #define MACRO(m) int m = 0
 
Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
===
--- clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -486,6 +486,9 @@
   NamingCheckFailure  = NamingCheckFailures[ID];
   SourceRange Range(MacroNameTok.getLocation(), MacroNameTok.getEndLoc());
 
+  if (!isValidAsciiIdentifier(Info.Fixup))
+Failure.FixStatus = ShouldFixStatus::FixInvalidIdentifier;
+
   Failure.Info = std::move(Info);
   addUsage(ID, Range);
 }


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -171,6 +171,11 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: declaration uses identifier '_', which is reserved in the global namespace; cannot be fixed automatically [bugprone-reserved-identifier]
 // CHECK-FIXES: {{^}}int _;{{$}}
 
+// https://github.com/llvm/llvm-project/issues/52895
+#define _5_kmph_rpm 459
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses identifier '_5_kmph_rpm', which is reserved in the global namespace; cannot be fixed automatically [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define _5_kmph_rpm 459{{$}}
+
 // these should pass
 #define MACRO(m) int m = 0
 
Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
===
--- clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -486,6 +486,9 @@
   NamingCheckFailure  = NamingCheckFailures[ID];
   SourceRange Range(MacroNameTok.getLocation(), MacroNameTok.getEndLoc());
 
+  if (!isValidAsciiIdentifier(Info.Fixup))
+Failure.FixStatus = ShouldFixStatus::FixInvalidIdentifier;
+
   Failure.Info = std::move(Info);
   addUsage(ID, Range);
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115374: [NFC][clang] Return std::strings built from raw_string_ostreams more efficiently

2021-12-09 Thread Logan Smith via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG715c72b4fbf4: [NFC][analyzer] Return underlying strings 
directly instead of OS.str() (authored by logan-5).

Changed prior to commit:
  https://reviews.llvm.org/D115374?vs=393262=393319#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115374/new/

https://reviews.llvm.org/D115374

Files:
  clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
  clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
  clang/lib/StaticAnalyzer/Core/MemRegion.cpp

Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -444,7 +444,7 @@
   std::string s;
   llvm::raw_string_ostream os(s);
   dumpToStream(os);
-  return os.str();
+  return s;
 }
 
 void MemRegion::dumpToStream(raw_ostream ) const {
Index: clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
===
--- clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -437,7 +437,7 @@
   for (auto BI : *Buf)
 os << BI;
 
-  return os.str();
+  return file;
 }
 
 void HTMLDiagnostics::dumpCoverageData(
@@ -534,7 +534,7 @@
 
 )<<<";
 
-  return os.str();
+  return s;
 }
 
 void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter ,
@@ -1202,7 +1202,7 @@
   std::string Result;
   llvm::raw_string_ostream OS(Result);
   OS << "";
-  return OS.str();
+  return Result;
 }
 
 std::string getSpanBeginForControlStart(unsigned Index) {
Index: clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
@@ -389,7 +389,7 @@
 llvm::raw_string_ostream OS(SBuf);
 OS << "Function '" << FuncDecl->getDeclName()
<< "' returns an open handle";
-return OS.str();
+return SBuf;
   } else
 return "";
 });
@@ -405,7 +405,7 @@
 llvm::raw_string_ostream OS(SBuf);
 OS << "Function '" << FuncDecl->getDeclName()
<< "' returns an unowned handle";
-return OS.str();
+return SBuf;
   } else
 return "";
 });
@@ -439,7 +439,7 @@
   llvm::raw_string_ostream OS(SBuf);
   OS << "Handle released through " << ParamDiagIdx
  << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
-  return OS.str();
+  return SBuf;
 } else
   return "";
   });
@@ -453,7 +453,7 @@
 llvm::raw_string_ostream OS(SBuf);
 OS << "Handle allocated through " << ParamDiagIdx
<< llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
-return OS.str();
+return SBuf;
   } else
 return "";
 });
@@ -467,7 +467,7 @@
 llvm::raw_string_ostream OS(SBuf);
 OS << "Unowned handle allocated through " << ParamDiagIdx
<< llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
-return OS.str();
+return SBuf;
   } else
 return "";
 });
Index: clang/lib/Analysis/AnalysisDeclContext.cpp
===
--- clang/lib/Analysis/AnalysisDeclContext.cpp
+++ clang/lib/Analysis/AnalysisDeclContext.cpp
@@ -387,7 +387,7 @@
 OS << ' ' << OMD->getSelector().getAsString() << ']';
   }
 
-  return OS.str();
+  return Str;
 }
 
 LocationContextManager ::getLocationContextManager() {
Index: clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
===
--- clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
+++ clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
@@ -32,7 +32,7 @@
 std::string Str;
 llvm::raw_string_ostream OS(Str);
 S->printPretty(OS, nullptr, PrintingPolicy(ACtx.getLangOpts()));
-return OS.str();
+return Str;
   }
 
   bool isThisObject(const SymbolicRegion *R) {
@@ -69,7 +69,7 @@
 std::string Str;
 llvm::raw_string_ostream OS(Str);
 OS << "concrete memory address '" << I << "'";
-return OS.str();
+return Str;
   }
 
   std::string VisitNonLocSymbolVal(nonloc::SymbolVal V) {
@@ -82,7 +82,7 @@
 llvm::raw_string_ostream OS(Str);
 OS << (I.isSigned() ? "signed " : "unsigned ") << I.getBitWidth()
<< "-bit integer '" << I << "'";
-return OS.str();
+return Str;
   }
 
   std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V) {
@@ -123,7 +123,7 @@

[PATCH] D115374: [NFC][clang] Return std::strings built from raw_string_ostreams more efficiently

2021-12-09 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 393262.
logan-5 added a comment.

Removed `.flush()`es. Seems like this might be able to land without 
https://reviews.llvm.org/D115421?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115374/new/

https://reviews.llvm.org/D115374

Files:
  clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
  clang/include/clang/Testing/TestClangConfig.h
  clang/lib/AST/ASTDiagnostic.cpp
  clang/lib/AST/AttrImpl.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclarationName.cpp
  clang/lib/AST/OpenMPClause.cpp
  clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/Basic/SourceLocation.cpp
  clang/lib/Basic/Version.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Frontend/TestModuleFileExtension.cpp
  clang/lib/Rewrite/HTMLRewrite.cpp
  clang/lib/Sema/CodeCompleteConsumer.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
  clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
  clang/lib/StaticAnalyzer/Core/MemRegion.cpp
  clang/lib/Tooling/Syntax/Tokens.cpp
  clang/lib/Tooling/Syntax/Tree.cpp
  clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
  clang/unittests/AST/ASTTraverserTest.cpp
  clang/unittests/Analysis/MacroExpansionContextTest.cpp
  clang/unittests/Tooling/Syntax/TreeTest.cpp

Index: clang/unittests/Tooling/Syntax/TreeTest.cpp
===
--- clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -203,7 +203,7 @@
 
 OS << "]";
 
-return OS.str();
+return Storage;
   }
 
   std::string dumpNodes(ArrayRef Nodes) {
@@ -218,7 +218,7 @@
 
 OS << "]";
 
-return OS.str();
+return Storage;
   }
 };
 
Index: clang/unittests/Analysis/MacroExpansionContextTest.cpp
===
--- clang/unittests/Analysis/MacroExpansionContextTest.cpp
+++ clang/unittests/Analysis/MacroExpansionContextTest.cpp
@@ -95,14 +95,14 @@
 std::string Buf;
 llvm::raw_string_ostream OS{Buf};
 Ctx.dumpExpandedTextsToStream(OS);
-return OS.str();
+return Buf;
   }
 
   static std::string dumpExpansionRanges(const MacroExpansionContext ) {
 std::string Buf;
 llvm::raw_string_ostream OS{Buf};
 Ctx.dumpExpansionRangesToStream(OS);
-return OS.str();
+return Buf;
   }
 };
 
Index: clang/unittests/AST/ASTTraverserTest.cpp
===
--- clang/unittests/AST/ASTTraverserTest.cpp
+++ clang/unittests/AST/ASTTraverserTest.cpp
@@ -111,7 +111,7 @@
 
   Dumper.Visit(std::forward(N)...);
 
-  return OS.str();
+  return Buffer;
 }
 
 template 
@@ -126,7 +126,7 @@
 
   Dumper.Visit(std::forward(N)...);
 
-  return OS.str();
+  return Buffer;
 }
 
 const FunctionDecl *getFunctionNode(clang::ASTUnit *AST,
Index: clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
===
--- clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
+++ clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
@@ -139,7 +139,7 @@
 
   Passes.run(*M);
 
-  return OS.str();
+  return outString;
 }
 
 // Takes a function and runs it on a set of inputs
Index: clang/lib/Tooling/Syntax/Tree.cpp
===
--- clang/lib/Tooling/Syntax/Tree.cpp
+++ clang/lib/Tooling/Syntax/Tree.cpp
@@ -263,7 +263,7 @@
   OS << " ";
 }
   });
-  return OS.str();
+  return Storage;
 }
 
 void syntax::Node::assertInvariants() const {
Index: clang/lib/Tooling/Syntax/Tokens.cpp
===
--- clang/lib/Tooling/Syntax/Tokens.cpp
+++ clang/lib/Tooling/Syntax/Tokens.cpp
@@ -927,5 +927,5 @@
   M.EndExpanded);
 }
   }
-  return OS.str();
+  return Dump;
 }
Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -444,7 +444,7 @@
   std::string s;
   llvm::raw_string_ostream os(s);
   dumpToStream(os);
-  return os.str();
+  return s;
 }
 
 void MemRegion::dumpToStream(raw_ostream ) const {
Index: clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
===
--- clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -437,7 +437,7 @@
   for (auto BI : *Buf)
 os << BI;
 
-  return os.str();
+  return file;
 }
 
 void HTMLDiagnostics::dumpCoverageData(
@@ -534,7 +534,7 @@
 
 )<<<";
 
-  return os.str();
+  return s;
 }
 
 void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter ,
@@ -1200,9 +1200,9 @@
 
 std::string getSpanBeginForControl(const char *ClassName, unsigned Index) {
   std::string Result;
-  

[PATCH] D115374: [NFC][clang] Return std::strings built from raw_string_ostreams more efficiently

2021-12-08 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

To be clear, it sounds like we should //either// add `.take()` for moving the 
string out of `raw_string_ostream`'s string reference, //or// make 
`raw_string_ostream` not need to be flushed (after which there won't be as 
clear a use for `.take()`, since you can just use the underlying string 
directly).

I vote for the second option, making `raw_string_ostream` not need to be 
flushed, since it allows for simpler code at the call site (`return Str;`), 
permits NRVO at the call site, and avoids some possibly weird questions 
`.take()` would bring with it (like whether it would ever be surprising that it 
moves out of a //reference// that someone else might also have).

If that's the direction that sounds best, I can submit an updated patch 
sometime tomorrow.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115374/new/

https://reviews.llvm.org/D115374

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


[PATCH] D115374: [NFC][clang] Return std::strings built from raw_string_ostreams more efficiently

2021-12-08 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 392996.
logan-5 added a comment.

Eliminate some explicit `.flush()`es by using temporary `raw_string_ostream`s 
where possible.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115374/new/

https://reviews.llvm.org/D115374

Files:
  clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
  clang/include/clang/Testing/TestClangConfig.h
  clang/lib/AST/ASTDiagnostic.cpp
  clang/lib/AST/AttrImpl.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclarationName.cpp
  clang/lib/AST/OpenMPClause.cpp
  clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/Basic/SourceLocation.cpp
  clang/lib/Basic/Version.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Frontend/TestModuleFileExtension.cpp
  clang/lib/Rewrite/HTMLRewrite.cpp
  clang/lib/Sema/CodeCompleteConsumer.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
  clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
  clang/lib/StaticAnalyzer/Core/MemRegion.cpp
  clang/lib/Tooling/Syntax/Tokens.cpp
  clang/lib/Tooling/Syntax/Tree.cpp
  clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
  clang/unittests/AST/ASTTraverserTest.cpp
  clang/unittests/Analysis/MacroExpansionContextTest.cpp
  clang/unittests/Tooling/Syntax/TreeTest.cpp

Index: clang/unittests/Tooling/Syntax/TreeTest.cpp
===
--- clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -203,7 +203,8 @@
 
 OS << "]";
 
-return OS.str();
+OS.flush();
+return Storage;
   }
 
   std::string dumpNodes(ArrayRef Nodes) {
@@ -218,7 +219,8 @@
 
 OS << "]";
 
-return OS.str();
+OS.flush();
+return Storage;
   }
 };
 
Index: clang/unittests/Analysis/MacroExpansionContextTest.cpp
===
--- clang/unittests/Analysis/MacroExpansionContextTest.cpp
+++ clang/unittests/Analysis/MacroExpansionContextTest.cpp
@@ -95,14 +95,16 @@
 std::string Buf;
 llvm::raw_string_ostream OS{Buf};
 Ctx.dumpExpandedTextsToStream(OS);
-return OS.str();
+OS.flush();
+return Buf;
   }
 
   static std::string dumpExpansionRanges(const MacroExpansionContext ) {
 std::string Buf;
 llvm::raw_string_ostream OS{Buf};
 Ctx.dumpExpansionRangesToStream(OS);
-return OS.str();
+OS.flush();
+return Buf;
   }
 };
 
Index: clang/unittests/AST/ASTTraverserTest.cpp
===
--- clang/unittests/AST/ASTTraverserTest.cpp
+++ clang/unittests/AST/ASTTraverserTest.cpp
@@ -111,7 +111,8 @@
 
   Dumper.Visit(std::forward(N)...);
 
-  return OS.str();
+  OS.flush();
+  return Buffer;
 }
 
 template 
@@ -126,7 +127,8 @@
 
   Dumper.Visit(std::forward(N)...);
 
-  return OS.str();
+  OS.flush();
+  return Buffer;
 }
 
 const FunctionDecl *getFunctionNode(clang::ASTUnit *AST,
Index: clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
===
--- clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
+++ clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
@@ -139,7 +139,8 @@
 
   Passes.run(*M);
 
-  return OS.str();
+  OS.flush();
+  return outString;
 }
 
 // Takes a function and runs it on a set of inputs
Index: clang/lib/Tooling/Syntax/Tree.cpp
===
--- clang/lib/Tooling/Syntax/Tree.cpp
+++ clang/lib/Tooling/Syntax/Tree.cpp
@@ -263,7 +263,8 @@
   OS << " ";
 }
   });
-  return OS.str();
+  OS.flush();
+  return Storage;
 }
 
 void syntax::Node::assertInvariants() const {
Index: clang/lib/Tooling/Syntax/Tokens.cpp
===
--- clang/lib/Tooling/Syntax/Tokens.cpp
+++ clang/lib/Tooling/Syntax/Tokens.cpp
@@ -927,5 +927,6 @@
   M.EndExpanded);
 }
   }
-  return OS.str();
+  OS.flush();
+  return Dump;
 }
Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -444,7 +444,8 @@
   std::string s;
   llvm::raw_string_ostream os(s);
   dumpToStream(os);
-  return os.str();
+  os.flush();
+  return s;
 }
 
 void MemRegion::dumpToStream(raw_ostream ) const {
Index: clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
===
--- clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -437,7 +437,8 @@
   for (auto BI : *Buf)
 os << BI;
 
-  return os.str();
+  os.flush();
+  return file;
 }
 
 void HTMLDiagnostics::dumpCoverageData(
@@ -534,7 +535,8 @@
 
 )<<<";
 
-  return os.str();
+  os.flush();
+  return s;
 }
 
 void 

[PATCH] D115374: [NFC][clang] Return std::strings built from raw_string_ostreams more efficiently

2021-12-08 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D115374#3181383 , @dexonsmith 
wrote:

> I don't feel strongly, but IMO the code might be a bit harder to 
> read/maintain with the explicit flush. I worry that it'd be easy to move the 
> `flush()` away from the `return`. Not sure I'm right; could just be 
> familiarity with `str()`.

I definitely hear you. I don't really mind it personally, and I did it this way 
because I saw precedent in a couple spots (there's one on 
CompilerInvocation.cpp:653, several in clangd, etc.). I definitely see how it 
could be a little bit spooky though.

>   std::string Str;
>   llvm::raw_string_ostream(Str) << ...;
>   return Str;

I like this idea. I'd be happy to go back through and change the simple ones to 
this pattern.

> Another option:
>
>   std::string Result;
>   llvm::raw_string_ostream OS(Str);
>   OS << ...;
>   return OS.take();
>
> Where `raw_string_ostream::take()` is just `return std::move(str())`. It 
> doesn't get NRVO, but I'm not sure that really matters in most of these 
> places. Benefit is that it's a minimal change and the name is clear / matches 
> other LLVM things.

I suppose the question then becomes whether to name it `take()` or `str() &&` 
for symmetry with C++20's `std::ostringstream`. (Also for the record, I agree 
that NRVOing some std::strings isn't going to make a giant difference; my 
opinion is simply that if we can get it, we might as well.)




Comment at: clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h:36
+OS.flush();
+return Str;
   }

dexonsmith wrote:
> logan-5 wrote:
> > Quuxplusone wrote:
> > > FWIW, it appears to me that in most (all?) of these cases, what's really 
> > > wanted is not "a string //and// a stream" but rather "a stream that owns 
> > > a string" (`std::ostringstream` or the LLVM-codebase equivalent thereof). 
> > > Then the return can be `return std::move(OS).str();` — for 
> > > `std::ostringstream`, this Does The Right Thing since C++20, and if LLVM 
> > > had its own stringstream it could make it Do The Right Thing today.
> > > https://en.cppreference.com/w/cpp/io/basic_ostringstream/str
> > > 
> > True enough. Although `return std::move(OS).str();` is still much harder to 
> > type than the less efficient `return OS.str();`, and it requires at minimum 
> > a move of the underlying string--whereas `return Str;` is the easiest of 
> > all to type, and it opens things up for NRVO. If (as I said in the patch 
> > summary) `raw_string_ostream` were changed to be guaranteed to not need 
> > flushing, `return Str;` would IMHO be cemented as the clear winner.
> > 
> > That said, you're clearly right that all these cases are semantically 
> > trying to do "a stream that owns a string", and it's clunky to execute with 
> > the existing APIs.
> >  If (as I said in the patch summary) raw_string_ostream were changed to be 
> > guaranteed to not need flushing
> 
> This sounds like a one-line patch; might be better to just do it rather than 
> having to churn all these things twice.
> >  If (as I said in the patch summary) raw_string_ostream were changed to be 
> > guaranteed to not need flushing
> 
> This sounds like a one-line patch; might be better to just do it rather than 
> having to churn all these things twice.

I guess this change kind of freaks me out. Currently you can call 
`SetBuffered()` on `raw_string_ostream` (though I don't know why you would...), 
which creates an intermediate buffer and then `flush()` syncs the buffer with 
the underlying `std::string&`. Removing that ability would be a breaking 
change, and I'm not sure how we could make it while being confident we're not 
breaking anything downstream. 

(On the other hand, you can call `SetBuffered()` on `raw_svector_ostream` too, 
whose documentation more or less says it doesn't support buffering. If I'm 
reading right, you get an assert failure in `~raw_ostream()` if you do.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115374/new/

https://reviews.llvm.org/D115374

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


[PATCH] D115374: [NFC][clang] Return std::strings built from raw_string_ostreams more efficiently

2021-12-08 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added inline comments.



Comment at: clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h:36
+OS.flush();
+return Str;
   }

Quuxplusone wrote:
> FWIW, it appears to me that in most (all?) of these cases, what's really 
> wanted is not "a string //and// a stream" but rather "a stream that owns a 
> string" (`std::ostringstream` or the LLVM-codebase equivalent thereof). Then 
> the return can be `return std::move(OS).str();` — for `std::ostringstream`, 
> this Does The Right Thing since C++20, and if LLVM had its own stringstream 
> it could make it Do The Right Thing today.
> https://en.cppreference.com/w/cpp/io/basic_ostringstream/str
> 
True enough. Although `return std::move(OS).str();` is still much harder to 
type than the less efficient `return OS.str();`, and it requires at minimum a 
move of the underlying string--whereas `return Str;` is the easiest of all to 
type, and it opens things up for NRVO. If (as I said in the patch summary) 
`raw_string_ostream` were changed to be guaranteed to not need flushing, 
`return Str;` would IMHO be cemented as the clear winner.

That said, you're clearly right that all these cases are semantically trying to 
do "a stream that owns a string", and it's clunky to execute with the existing 
APIs.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115374/new/

https://reviews.llvm.org/D115374

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


[PATCH] D115374: [NFC][clang] Return std::strings built from raw_string_ostreams more efficiently

2021-12-08 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added a reviewer: aaron.ballman.
logan-5 added a project: clang.
Herald added subscribers: abrachet, ctetreau, dexonsmith, martong.
logan-5 requested review of this revision.
Herald added a subscriber: cfe-commits.

Returning `OS.str()` is guaranteed to copy the underlying string, whereas 
`OS.flush(); return Underlying;` makes `Underlying` a candidate for NRVO, or at 
worst, implicit move.

To keep this kind of inefficiency at bay in the future, the fast code should 
probably be made easier to type than the slow code (as it's currently the 
opposite). Perhaps this could be solved by:

- making `raw_string_ostream` guarantee+document that it does not need to be 
`flush()`ed (similar to `raw_svector_ostream`), //and/or//
- making `raw_string_ostream::str()` return a `StringRef` rather than 
`std::string&`, to discourage using it to initialize `std::string`s

Implementing those two ideas would make simply `return Underlying;` the 
natural, correct, and efficient choice. They are, however, out of scope for 
this patch.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115374

Files:
  clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
  clang/include/clang/Testing/TestClangConfig.h
  clang/lib/AST/ASTDiagnostic.cpp
  clang/lib/AST/AttrImpl.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclarationName.cpp
  clang/lib/AST/OpenMPClause.cpp
  clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/Basic/SourceLocation.cpp
  clang/lib/Basic/Version.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Frontend/TestModuleFileExtension.cpp
  clang/lib/Rewrite/HTMLRewrite.cpp
  clang/lib/Sema/CodeCompleteConsumer.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
  clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
  clang/lib/StaticAnalyzer/Core/MemRegion.cpp
  clang/lib/Tooling/Syntax/Tokens.cpp
  clang/lib/Tooling/Syntax/Tree.cpp
  clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
  clang/unittests/AST/ASTTraverserTest.cpp
  clang/unittests/Analysis/MacroExpansionContextTest.cpp
  clang/unittests/Tooling/Syntax/TreeTest.cpp

Index: clang/unittests/Tooling/Syntax/TreeTest.cpp
===
--- clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -203,7 +203,8 @@
 
 OS << "]";
 
-return OS.str();
+OS.flush();
+return Storage;
   }
 
   std::string dumpNodes(ArrayRef Nodes) {
@@ -218,7 +219,8 @@
 
 OS << "]";
 
-return OS.str();
+OS.flush();
+return Storage;
   }
 };
 
Index: clang/unittests/Analysis/MacroExpansionContextTest.cpp
===
--- clang/unittests/Analysis/MacroExpansionContextTest.cpp
+++ clang/unittests/Analysis/MacroExpansionContextTest.cpp
@@ -95,14 +95,16 @@
 std::string Buf;
 llvm::raw_string_ostream OS{Buf};
 Ctx.dumpExpandedTextsToStream(OS);
-return OS.str();
+OS.flush();
+return Buf;
   }
 
   static std::string dumpExpansionRanges(const MacroExpansionContext ) {
 std::string Buf;
 llvm::raw_string_ostream OS{Buf};
 Ctx.dumpExpansionRangesToStream(OS);
-return OS.str();
+OS.flush();
+return Buf;
   }
 };
 
Index: clang/unittests/AST/ASTTraverserTest.cpp
===
--- clang/unittests/AST/ASTTraverserTest.cpp
+++ clang/unittests/AST/ASTTraverserTest.cpp
@@ -111,7 +111,8 @@
 
   Dumper.Visit(std::forward(N)...);
 
-  return OS.str();
+  OS.flush();
+  return Buffer;
 }
 
 template 
@@ -126,7 +127,8 @@
 
   Dumper.Visit(std::forward(N)...);
 
-  return OS.str();
+  OS.flush();
+  return Buffer;
 }
 
 const FunctionDecl *getFunctionNode(clang::ASTUnit *AST,
Index: clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
===
--- clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
+++ clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
@@ -139,7 +139,8 @@
 
   Passes.run(*M);
 
-  return OS.str();
+  OS.flush();
+  return outString;
 }
 
 // Takes a function and runs it on a set of inputs
Index: clang/lib/Tooling/Syntax/Tree.cpp
===
--- clang/lib/Tooling/Syntax/Tree.cpp
+++ clang/lib/Tooling/Syntax/Tree.cpp
@@ -263,7 +263,8 @@
   OS << " ";
 }
   });
-  return OS.str();
+  OS.flush();
+  return Storage;
 }
 
 void syntax::Node::assertInvariants() const {
Index: clang/lib/Tooling/Syntax/Tokens.cpp
===
--- clang/lib/Tooling/Syntax/Tokens.cpp
+++ clang/lib/Tooling/Syntax/Tokens.cpp
@@ -927,5 +927,6 @@
   M.EndExpanded);
 }
   }
-  return OS.str();
+  OS.flush();
+  return Dump;
 }
Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp

[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2021-12-08 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

It's been a year and a half since I heard anything about this patch and I'd 
honestly kind of forgotten about it. I'm still around/lurking though, and would 
assist with getting it landed if it's still good to go.




Comment at: clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp:27
+  Decl.printNestedNameSpecifier(OS, Decl.getASTContext().getPrintingPolicy());
+  return OS.str();
+}

Oops: this should maybe be `OS.flush(); return N;` so that N is NRVO'd or else 
implicit-moved. `return OS.str();` does a copy.



Comment at: clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp:127
+OS << ", '" << (*Begin)->getType().getAsString() << "'";
+  return Result;
+}

I can't imagine it super matters for raw_string_ostream, but I think 
pedantically this needs an `OS.flush()` before the return.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282

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


[PATCH] D102338: [Sema] Always search the full function scope context if a potential availability violation is encountered

2021-05-24 Thread Logan Smith via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa5a3efa82a77: [Sema] Always search the full function scope 
context if a potential… (authored by logan-5).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102338/new/

https://reviews.llvm.org/D102338

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaAvailability.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaObjC/unguarded-availability.m

Index: clang/test/SemaObjC/unguarded-availability.m
===
--- clang/test/SemaObjC/unguarded-availability.m
+++ clang/test/SemaObjC/unguarded-availability.m
@@ -125,6 +125,14 @@
   (void) ^{
 func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
   };
+
+  if (@available(macos 10.12, *))
+(void) ^{
+  func_10_12();
+  (void) ^{
+func_10_12();
+  };
+};
 }
 
 void test_params(int_10_12 x); // expected-warning {{'int_10_12' is only available on macOS 10.12 or newer}} expected-note{{annotate 'test_params' with an availability attribute to silence this warning}}
@@ -233,6 +241,36 @@
   (void)(^ {
 func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
   });
+
+  if (@available(macos 10.12, *)) {
+void([]() {
+  func_10_12();
+  void([] () {
+func_10_12();
+  });
+  struct DontWarn {
+void f() {
+  func_10_12();
+}
+  };
+});
+  }
+
+  if (@available(macos 10.12, *)) {
+struct DontWarn {
+  void f() {
+func_10_12();
+void([] () {
+  func_10_12();
+});
+struct DontWarn2 {
+  void f() {
+func_10_12();
+  }
+};
+  }
+};
+  }
 }
 
 #endif
@@ -259,9 +297,14 @@
 @end
 
 void with_local_struct() {
-  struct local { // expected-note{{annotate 'local' with an availability attribute}}
-new_int x; // expected-warning{{'new_int' is only available}}
+  struct local { 
+new_int x; // expected-warning{{'new_int' is only available}} expected-note{{enclose 'new_int' in an @available check}}
   };
+  if (@available(macos 10.12, *)) {
+struct DontWarn {
+  new_int x;
+};
+  }
 }
 
 // rdar://33156429:
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -19650,12 +19650,10 @@
   if (Spec != AvailSpecs.end())
 Version = Spec->getVersion();
 
-  // The use of `@available` in the enclosing function should be analyzed to
+  // The use of `@available` in the enclosing context should be analyzed to
   // warn when it's used inappropriately (i.e. not if(@available)).
-  if (getCurFunctionOrMethodDecl())
-getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
-  else if (getCurBlock() || getCurLambda())
-getCurFunction()->HasPotentialAvailabilityViolations = true;
+  if (FunctionScopeInfo *Context = getCurFunctionAvailabilityContext())
+Context->HasPotentialAvailabilityViolations = true;
 
   return new (Context)
   ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy);
Index: clang/lib/Sema/SemaAvailability.cpp
===
--- clang/lib/Sema/SemaAvailability.cpp
+++ clang/lib/Sema/SemaAvailability.cpp
@@ -666,13 +666,6 @@
 SemaRef.Context.getTargetInfo().getPlatformMinVersion());
   }
 
-  bool TraverseDecl(Decl *D) {
-// Avoid visiting nested functions to prevent duplicate warnings.
-if (!D || isa(D))
-  return true;
-return Base::TraverseDecl(D);
-  }
-
   bool TraverseStmt(Stmt *S) {
 if (!S)
   return true;
@@ -686,8 +679,6 @@
 
   bool TraverseIfStmt(IfStmt *If);
 
-  bool TraverseLambdaExpr(LambdaExpr *E) { return true; }
-
   // for 'case X:' statements, don't bother looking at the 'X'; it can't lead
   // to any useful diagnostics.
   bool TraverseCaseStmt(CaseStmt *CS) { return TraverseStmt(CS->getSubStmt()); }
@@ -919,6 +910,17 @@
   DiagnoseUnguardedAvailability(*this, D).IssueDiagnostics(Body);
 }
 
+FunctionScopeInfo *Sema::getCurFunctionAvailabilityContext() {
+  if (FunctionScopes.empty())
+return nullptr;
+
+  // Conservatively search the entire current function scope context for
+  // availability violations. This ensures we always correctly analyze nested
+  // classes, blocks, lambdas, etc. that may or may not be inside if(@available)
+  // checks themselves.
+  return FunctionScopes.front();
+}
+
 void Sema::DiagnoseAvailabilityOfDecl(NamedDecl *D,
   ArrayRef Locs,
   const ObjCInterfaceDecl *UnknownObjCClass,
@@ -941,11 +943,8 @@
 // We need to know the @available context in the current function to
 // 

[PATCH] D102338: [Sema] Always search the full function scope context if a potential availability violation is encountered

2021-05-22 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Thanks very much; I look forward to any feedback!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102338/new/

https://reviews.llvm.org/D102338

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


[PATCH] D102338: [Sema] Always search the full function scope context if a potential availability violation is encountered

2021-05-12 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added reviewers: erik.pilkington, rsmith, arphaman.
logan-5 added a project: clang.
logan-5 requested review of this revision.
Herald added a subscriber: cfe-commits.

Always search the full function scope context if a potential availability 
violation is encountered. This fixes both 
https://bugs.llvm.org/show_bug.cgi?id=50309 and 
https://bugs.llvm.org/show_bug.cgi?id=50310.

Previously, lambdas inside functions would mark their own bodies for later 
analysis when encountering a potentially unavailable decl, without taking into 
consideration that the entire lambda itself might be correctly guarded inside 
an `@available` check. The same applied to inner class member functions. Blocks 
happened to work as expected already, since `Sema::getEnclosingFunction()` 
skips through block scopes.

This patch instead simply and conservatively marks the entire outermost 
function scope for search, and removes some special-case logic that prevented 
`DiagnoseUnguardedAvailabilityViolations` from traversing down into lambdas and 
nested functions. This correctly accounts for arbitrarily nested lambdas, inner 
classes, and blocks that may be inside appropriate `@available` checks at any 
ancestor level. It also treats all potential availability violations inside 
functions consistently, without being overly sensitive to the current 
DeclContext, which previously caused issues where e.g. nested struct members 
were warned about twice.

`DiagnoseUnguardedAvailabilityViolations` now has more work to do in some 
cases, particularly in functions with many (possibly deeply) nested lambdas and 
classes, but the big-O is the same, and the simplicity of the approach and the 
fact that it fixes at least two bugs feels like a strong win IMO.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D102338

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaAvailability.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaObjC/unguarded-availability.m

Index: clang/test/SemaObjC/unguarded-availability.m
===
--- clang/test/SemaObjC/unguarded-availability.m
+++ clang/test/SemaObjC/unguarded-availability.m
@@ -125,6 +125,14 @@
   (void) ^{
 func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
   };
+
+  if (@available(macos 10.12, *))
+(void) ^{
+  func_10_12();
+  (void) ^{
+func_10_12();
+  };
+};
 }
 
 void test_params(int_10_12 x); // expected-warning {{'int_10_12' is only available on macOS 10.12 or newer}} expected-note{{annotate 'test_params' with an availability attribute to silence this warning}}
@@ -233,6 +241,36 @@
   (void)(^ {
 func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
   });
+
+  if (@available(macos 10.12, *)) {
+void([]() {
+  func_10_12();
+  void([] () {
+func_10_12();
+  });
+  struct DontWarn {
+void f() {
+  func_10_12();
+}
+  };
+});
+  }
+
+  if (@available(macos 10.12, *)) {
+struct DontWarn {
+  void f() {
+func_10_12();
+void([] () {
+  func_10_12();
+});
+struct DontWarn2 {
+  void f() {
+func_10_12();
+  }
+};
+  }
+};
+  }
 }
 
 #endif
@@ -259,9 +297,14 @@
 @end
 
 void with_local_struct() {
-  struct local { // expected-note{{annotate 'local' with an availability attribute}}
-new_int x; // expected-warning{{'new_int' is only available}}
+  struct local { 
+new_int x; // expected-warning{{'new_int' is only available}} expected-note{{enclose 'new_int' in an @available check}}
   };
+  if (@available(macos 10.12, *)) {
+struct DontWarn {
+  new_int x;
+};
+  }
 }
 
 // rdar://33156429:
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -19653,12 +19653,10 @@
   if (Spec != AvailSpecs.end())
 Version = Spec->getVersion();
 
-  // The use of `@available` in the enclosing function should be analyzed to
+  // The use of `@available` in the enclosing context should be analyzed to
   // warn when it's used inappropriately (i.e. not if(@available)).
-  if (getCurFunctionOrMethodDecl())
-getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
-  else if (getCurBlock() || getCurLambda())
-getCurFunction()->HasPotentialAvailabilityViolations = true;
+  if (FunctionScopeInfo *Context = getCurFunctionAvailabilityContext())
+Context->HasPotentialAvailabilityViolations = true;
 
   return new (Context)
   ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy);
Index: clang/lib/Sema/SemaAvailability.cpp
===
--- 

[PATCH] D84554: Use INTERFACE_COMPILE_OPTIONS to disable -Wsuggest-override for any target that links to gtest

2020-07-27 Thread Logan Smith via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa52aea0ba624: Use INTERFACE_COMPILE_OPTIONS to disable 
-Wsuggest-override for any target that… (authored by logan-5).

Changed prior to commit:
  https://reviews.llvm.org/D84554?vs=280564=280933#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84554/new/

https://reviews.llvm.org/D84554

Files:
  clang-tools-extra/clangd/unittests/CMakeLists.txt
  clang-tools-extra/unittests/CMakeLists.txt
  clang/unittests/CMakeLists.txt
  lld/unittests/CMakeLists.txt
  llvm/lib/Testing/Support/CMakeLists.txt
  llvm/unittests/CMakeLists.txt
  llvm/utils/unittest/CMakeLists.txt
  mlir/unittests/CMakeLists.txt
  polly/unittests/CMakeLists.txt

Index: polly/unittests/CMakeLists.txt
===
--- polly/unittests/CMakeLists.txt
+++ polly/unittests/CMakeLists.txt
@@ -19,10 +19,6 @@
   target_link_libraries(${test_name} PRIVATE Polly)
 endfunction()
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 add_subdirectory(Isl)
 add_subdirectory(Flatten)
 add_subdirectory(DeLICM)
Index: mlir/unittests/CMakeLists.txt
===
--- mlir/unittests/CMakeLists.txt
+++ mlir/unittests/CMakeLists.txt
@@ -5,10 +5,6 @@
   add_unittest(MLIRUnitTests ${test_dirname} ${ARGN})
 endfunction()
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 add_subdirectory(Analysis)
 add_subdirectory(Dialect)
 add_subdirectory(IR)
Index: llvm/utils/unittest/CMakeLists.txt
===
--- llvm/utils/unittest/CMakeLists.txt
+++ llvm/utils/unittest/CMakeLists.txt
@@ -43,9 +43,6 @@
 if(CXX_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG)
   add_definitions("-Wno-covered-switch-default")
 endif()
-if(CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_definitions("-Wno-suggest-override")
-endif()
 
 set(LLVM_REQUIRES_RTTI 1)
 add_definitions( -DGTEST_HAS_RTTI=0 )
@@ -73,6 +70,14 @@
   BUILDTREE_ONLY
 )
 
+# The googletest and googlemock sources don't presently use the 'override'
+# keyword, which leads to lots of warnings from -Wsuggest-override. Disable
+# that warning here for any targets that link to gtest.
+if(CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
+  add_definitions("-Wno-suggest-override")
+  set_target_properties(gtest PROPERTIES INTERFACE_COMPILE_OPTIONS "-Wno-suggest-override")
+endif()
+
 add_subdirectory(UnitTestMain)
 
 # When LLVM_LINK_LLVM_DYLIB is enabled, libLLVM.so is added to the interface
Index: llvm/unittests/CMakeLists.txt
===
--- llvm/unittests/CMakeLists.txt
+++ llvm/unittests/CMakeLists.txt
@@ -14,10 +14,6 @@
   add_llvm_unittest(${test_dir_name} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARGN})
 endfunction()
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 add_subdirectory(ADT)
 add_subdirectory(Analysis)
 add_subdirectory(AsmParser)
Index: llvm/lib/Testing/Support/CMakeLists.txt
===
--- llvm/lib/Testing/Support/CMakeLists.txt
+++ llvm/lib/Testing/Support/CMakeLists.txt
@@ -1,10 +1,6 @@
 add_definitions(-DGTEST_LANG_CXX11=1)
 add_definitions(-DGTEST_HAS_TR1_TUPLE=0)
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 add_llvm_library(LLVMTestingSupport
   Annotations.cpp
   Error.cpp
Index: lld/unittests/CMakeLists.txt
===
--- lld/unittests/CMakeLists.txt
+++ lld/unittests/CMakeLists.txt
@@ -12,9 +12,5 @@
   target_link_libraries(${test_dirname} ${LLVM_COMMON_LIBS})
 endfunction()
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 add_subdirectory(DriverTests)
 add_subdirectory(MachOTests)
Index: clang/unittests/CMakeLists.txt
===
--- clang/unittests/CMakeLists.txt
+++ clang/unittests/CMakeLists.txt
@@ -1,10 +1,6 @@
 add_custom_target(ClangUnitTests)
 set_target_properties(ClangUnitTests PROPERTIES FOLDER "Clang tests")
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 if(CLANG_BUILT_STANDALONE)
   # LLVMTestingSupport library is needed for some of the unittests.
   if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Testing/Support
Index: clang-tools-extra/unittests/CMakeLists.txt
===
--- clang-tools-extra/unittests/CMakeLists.txt
+++ clang-tools-extra/unittests/CMakeLists.txt
@@ -5,10 +5,6 @@
   add_unittest(ExtraToolsUnitTests ${test_dirname} ${ARGN})
 endfunction()
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")

[PATCH] D84554: Use INTERFACE_COMPILE_OPTIONS to disable -Wsuggest-override for any target that links to gtest

2020-07-27 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D84554#2175012 , @labath wrote:

> Could you elaborate on the lldb issue? I'd like to take a look at that...


It looks like lldb/unittests/TestingSupport/CMakeLists.txt and 
lldb/unittests/TestingSupport/Symbol/CMakeLists.txt both both manually pull in 
the googletest/googlemock headers via `include_directories`. It also seems, 
although I'm not sure, like they don't themselves link to gtest, since simply 
removing those `include_directories` didn't work.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84554/new/

https://reviews.llvm.org/D84554



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


[PATCH] D84554: Use INTERFACE_COMPILE_OPTIONS to disable -Wsuggest-override for any target that links to gtest

2020-07-24 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added a reviewer: labath.
Herald added subscribers: llvm-commits, cfe-commits, msifontes, jurahul, 
Kayjukh, grosul1, Joonsoo, stephenneuendorffer, liufengdb, aartbik, lucyrfox, 
mgester, arpith-jacob, nicolasvasilache, antiagainst, shauheen, jpienaar, 
rriddle, mehdi_amini, usaxena95, kadircet, arphaman, jkorous, hiraditya, mgorny.
Herald added a reviewer: bollu.
Herald added a reviewer: DavidTruby.
Herald added projects: clang, MLIR, LLVM.

This cleans up several CMakeLists.txt's where `-Wno-suggest-override` was 
manually specified. These test targets now inherit this flag from the gtest 
target.

Some unittests CMakeLists.txt's, in particular Flang and LLDB, are not touched 
by this patch. Flang manually adds the gtest sources itself in some 
configurations, rather than linking to LLVM's gtest target, so this fix would 
be insufficient to cover those cases. Similarly, LLDB has subdirectories that 
manually add the gtest headers to their include path without linking to the 
gtest target, so those subdirectories still need -Wno-suggest-override to be 
manually specified to compile without warnings.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84554

Files:
  clang-tools-extra/clangd/unittests/CMakeLists.txt
  clang-tools-extra/unittests/CMakeLists.txt
  clang/unittests/CMakeLists.txt
  lld/unittests/CMakeLists.txt
  llvm/lib/Testing/Support/CMakeLists.txt
  llvm/unittests/CMakeLists.txt
  llvm/utils/unittest/CMakeLists.txt
  mlir/unittests/CMakeLists.txt
  polly/unittests/CMakeLists.txt

Index: polly/unittests/CMakeLists.txt
===
--- polly/unittests/CMakeLists.txt
+++ polly/unittests/CMakeLists.txt
@@ -19,10 +19,6 @@
   target_link_libraries(${test_name} PRIVATE Polly)
 endfunction()
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 add_subdirectory(Isl)
 add_subdirectory(Flatten)
 add_subdirectory(DeLICM)
Index: mlir/unittests/CMakeLists.txt
===
--- mlir/unittests/CMakeLists.txt
+++ mlir/unittests/CMakeLists.txt
@@ -5,10 +5,6 @@
   add_unittest(MLIRUnitTests ${test_dirname} ${ARGN})
 endfunction()
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 add_subdirectory(Analysis)
 add_subdirectory(Dialect)
 add_subdirectory(IR)
Index: llvm/utils/unittest/CMakeLists.txt
===
--- llvm/utils/unittest/CMakeLists.txt
+++ llvm/utils/unittest/CMakeLists.txt
@@ -43,9 +43,6 @@
 if(CXX_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG)
   add_definitions("-Wno-covered-switch-default")
 endif()
-if(CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_definitions("-Wno-suggest-override")
-endif()
 
 set(LLVM_REQUIRES_RTTI 1)
 add_definitions( -DGTEST_HAS_RTTI=0 )
@@ -73,6 +70,14 @@
   BUILDTREE_ONLY
 )
 
+# The googletest and googlemock sources don't presently use the 'override' 
+# keyword, which leads to lots of warnings from -Wsuggest-override. Disable 
+# that warning here for any targets that link to gtest.
+if(CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
+  add_definitions("-Wno-suggest-override")
+  set_target_properties(gtest PROPERTIES INTERFACE_COMPILE_OPTIONS "-Wno-suggest-override")
+endif()
+
 add_subdirectory(UnitTestMain)
 
 # When LLVM_LINK_LLVM_DYLIB is enabled, libLLVM.so is added to the interface
Index: llvm/unittests/CMakeLists.txt
===
--- llvm/unittests/CMakeLists.txt
+++ llvm/unittests/CMakeLists.txt
@@ -14,10 +14,6 @@
   add_llvm_unittest(${test_dir_name} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARGN})
 endfunction()
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 add_subdirectory(ADT)
 add_subdirectory(Analysis)
 add_subdirectory(AsmParser)
Index: llvm/lib/Testing/Support/CMakeLists.txt
===
--- llvm/lib/Testing/Support/CMakeLists.txt
+++ llvm/lib/Testing/Support/CMakeLists.txt
@@ -1,10 +1,6 @@
 add_definitions(-DGTEST_LANG_CXX11=1)
 add_definitions(-DGTEST_HAS_TR1_TUPLE=0)
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 add_llvm_library(LLVMTestingSupport
   Annotations.cpp
   Error.cpp
Index: lld/unittests/CMakeLists.txt
===
--- lld/unittests/CMakeLists.txt
+++ lld/unittests/CMakeLists.txt
@@ -12,9 +12,5 @@
   target_link_libraries(${test_dirname} ${LLVM_COMMON_LIBS})
 endfunction()
 
-if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
-  add_compile_options("-Wno-suggest-override")
-endif()
-
 add_subdirectory(DriverTests)
 add_subdirectory(MachOTests)
Index: clang/unittests/CMakeLists.txt
===
--- clang/unittests/CMakeLists.txt
+++ 

[PATCH] D84244: [clang] Disable -Wsuggest-override for unittests/

2020-07-23 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D84244#2169142 , @hans wrote:

> Looks good to me so far. We haven't tried doing any full builds yet, but I 
> checked for the specific problem I hit yesterday (building 
> ClangApplyReplacementsTests) and that's working fine now.


Glad to hear that. I'll be keeping my eye on things today, but they look good 
so far to me too.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84244/new/

https://reviews.llvm.org/D84244



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


[PATCH] D84244: [clang] Disable -Wsuggest-override for unittests/

2020-07-22 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D84244#2167663 , @dblaikie wrote:

> Sometimes it's OK to commit stuff an see how it goes on the buildbots - doing 
> so out of peak times and with the intention of rolling back 
> quickly/immediately if the buildbots report breakage is sometimes the best 
> tool we have (not great, but such is the way of things).


In that case, I've enabled it again using `add_compile_options` instead of 
`add_definitions`. I've got my finger hovering over the button to revert.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84244/new/

https://reviews.llvm.org/D84244



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


[PATCH] D84244: [clang] Disable -Wsuggest-override for unittests/

2020-07-22 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D84244#2167625 , @hans wrote:

> I don't really know why this doesn't happen with other warning flags, but I 
> think it would be better to add flags like this with add_compile_options 
> rather than add_compile_definitions. I imagine that would prevent it from 
> reaching rc.exe.


That sounds pretty reasonable. Without any way of testing the Windows setup 
myself though, I don't feel comfortable making that change.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84244/new/

https://reviews.llvm.org/D84244



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


[PATCH] D84244: [clang] Disable -Wsuggest-override for unittests/

2020-07-22 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Thanks for reverting--I agree that that's the right move at this point.

Pretty much totally out my depth here, and I don't have a way of debugging the 
Windows issue, so I'm not sure how to proceed. I'm tempted to just let this 
whole thing rest for now and maybe try again sometime in the future.

I didn't realize quite how much I was biting off by volunteering to do this. I 
want to apologize again for all the trouble.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84244/new/

https://reviews.llvm.org/D84244



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


[PATCH] D84244: [clang] Disable -Wsuggest-override for unittests/

2020-07-21 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D84244#2165592 , @dblaikie wrote:

> Looks OK (for future reference, this sort of stuff should've been cleaned up 
> before enabling the flag so as to avoid this kind of hurry/breakage/etc)


Loud and clear. I honestly thought I had sifted through and dealt with all 
these before enabling it, but I was wrong. My mistake, I'm sorry about that.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84244/new/

https://reviews.llvm.org/D84244



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


[PATCH] D84244: [clang] Disable -Wsuggest-override for unittests/

2020-07-21 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Committing this now to fix the bots, as per discussion in 
https://reviews.llvm.org/D84126. I'll happily revert and approach it 
differently later if anyone requests that.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84244/new/

https://reviews.llvm.org/D84244



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


[PATCH] D84244: [clang] Disable -Wsuggest-override for unittests/

2020-07-21 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D84244#2164537 , @Quuxplusone wrote:

> For GTest and GMock specifically, it would be a good medium-term idea to try 
> to upstream patches into those libraries. I did eventually have success 
> upstreaming fixes for `-Wdeprecated` into GTest, for example: 
> https://github.com/google/googletest/pull/2815


Nice, that's encouraging. That does sound like a good solution for slightly 
further down the road.

> (Although I'm a bit confused; I thought `-Wsuggest-override` was 
> off-by-default? Is it part of `-Wall`, and do unittests add `-Wall` to their 
> command line or something?)

After I implemented the warning and it landed, people wanted it explicitly 
turned on in the LLVM build, so then I did that. This is part of the fallout 
from that.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84244/new/

https://reviews.llvm.org/D84244



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


[PATCH] D84213: [clang-tools-extra] Disable -Wsuggest-override for unittests/

2020-07-21 Thread Logan Smith via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGfa42b7cf2949: [clang-tools-extra] Disable -Wsuggest-override 
for unittests/ (authored by logan-5).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84213/new/

https://reviews.llvm.org/D84213

Files:
  clang-tools-extra/unittests/CMakeLists.txt


Index: clang-tools-extra/unittests/CMakeLists.txt
===
--- clang-tools-extra/unittests/CMakeLists.txt
+++ clang-tools-extra/unittests/CMakeLists.txt
@@ -5,6 +5,10 @@
   add_unittest(ExtraToolsUnitTests ${test_dirname} ${ARGN})
 endfunction()
 
+if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
+  add_definitions("-Wno-suggest-override")
+endif()
+
 add_subdirectory(clang-apply-replacements)
 add_subdirectory(clang-change-namespace)
 add_subdirectory(clang-doc)


Index: clang-tools-extra/unittests/CMakeLists.txt
===
--- clang-tools-extra/unittests/CMakeLists.txt
+++ clang-tools-extra/unittests/CMakeLists.txt
@@ -5,6 +5,10 @@
   add_unittest(ExtraToolsUnitTests ${test_dirname} ${ARGN})
 endfunction()
 
+if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
+  add_definitions("-Wno-suggest-override")
+endif()
+
 add_subdirectory(clang-apply-replacements)
 add_subdirectory(clang-change-namespace)
 add_subdirectory(clang-doc)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84244: [clang] Disable -Wsuggest-override for unittests/

2020-07-21 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added a reviewer: mgorny.
logan-5 added a project: clang.
Herald added a subscriber: cfe-commits.

Yesterday I enabled `-Wsuggest-override` in the main LLVM build and have been 
fighting with the -Werror bots ever since. The key culprits making this 
difficult are googletest and googlemock, which do not use the `override` 
keyword in their sources, so any files that include them are met with massive 
warning (or error, in the case of -Werror) spam.

I've been going through and playing whack-a-mole by adding 
`-Wno-suggest-override` to directories that have code that uses gtest and/or 
gmock; this approach is feeling increasingly inelegant the more I do it, but 
all the patches I've submitted for review have been LGTM'd so far.

I'm wondering if I should do this a different way, or if it's fine to just 
proceed along this path until the bots are green again.

Thank you for your review.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84244

Files:
  clang/unittests/CMakeLists.txt


Index: clang/unittests/CMakeLists.txt
===
--- clang/unittests/CMakeLists.txt
+++ clang/unittests/CMakeLists.txt
@@ -10,6 +10,10 @@
   endif()
 endif()
 
+if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
+  add_definitions("-Wno-suggest-override")
+endif()
+
 # add_clang_unittest(test_dirname file1.cpp file2.cpp)
 #
 # Will compile the list of files together and link against the clang


Index: clang/unittests/CMakeLists.txt
===
--- clang/unittests/CMakeLists.txt
+++ clang/unittests/CMakeLists.txt
@@ -10,6 +10,10 @@
   endif()
 endif()
 
+if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
+  add_definitions("-Wno-suggest-override")
+endif()
+
 # add_clang_unittest(test_dirname file1.cpp file2.cpp)
 #
 # Will compile the list of files together and link against the clang
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84213: [clang-tools-extra] Disable -Wsuggest-override for unittests/

2020-07-20 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added reviewers: aaron.ballman, klimek, alexfh, juliehockett, sammccall.
logan-5 added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, mgorny.
Herald added a project: clang.

I added `-Wsuggest-override` to the LLVM build earlier today, and have been 
putting out small fires I caused since then. One sticky area here has been 
directories that have files that include googlemock and/or googletest headers, 
which unfortunately do not themselves use `override`, so I've had to add 
`-Wno-suggest-override` to the CMakeLists.txt's in those directories. This 
patch adds this same flag to CMakeLists.txt in clang-tools-extra/unittests. I 
just wanted to get the LGTM from one or more of you fine folks before I 
committed it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84213

Files:
  clang-tools-extra/unittests/CMakeLists.txt


Index: clang-tools-extra/unittests/CMakeLists.txt
===
--- clang-tools-extra/unittests/CMakeLists.txt
+++ clang-tools-extra/unittests/CMakeLists.txt
@@ -5,6 +5,10 @@
   add_unittest(ExtraToolsUnitTests ${test_dirname} ${ARGN})
 endfunction()
 
+if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
+  add_definitions("-Wno-suggest-override")
+endif()
+
 add_subdirectory(clang-apply-replacements)
 add_subdirectory(clang-change-namespace)
 add_subdirectory(clang-doc)


Index: clang-tools-extra/unittests/CMakeLists.txt
===
--- clang-tools-extra/unittests/CMakeLists.txt
+++ clang-tools-extra/unittests/CMakeLists.txt
@@ -5,6 +5,10 @@
   add_unittest(ExtraToolsUnitTests ${test_dirname} ${ARGN})
 endfunction()
 
+if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
+  add_definitions("-Wno-suggest-override")
+endif()
+
 add_subdirectory(clang-apply-replacements)
 add_subdirectory(clang-change-namespace)
 add_subdirectory(clang-doc)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-19 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D82728#2161152 , @xbolva00 wrote:

> Is it possible to emit fixit note with "override" ?


This is a good idea, though unfortunately (after eyeballing the implementation 
of `modernize-use-override` in clang-tidy (UseOverrideCheck.cpp)), it looks 
non-trivial to figure out where exactly to insert `override`. There's some 
significant logic in the clang-tidy check involving re-lexing the relevant 
tokens, to find the insertion point in the presence of complexity like inline 
definitions, `= 0`, `= {delete|default}`, function try blocks, macros, and the 
list goes on.

The clang-tidy check has this FIXME comment to address the complexity 
(UseOverrideCheck.cpp:136):

  // FIXME: Instead of re-lexing and looking for specific macros such as
  // 'ABSTRACT', properly store the location of 'virtual' and '= 0' in each
  // FunctionDecl.

If this was done, the resulting information would presumably simplify the 
clang-tidy check as well as make it easier to add a fixit to this warning. This 
sounds like an interesting problem, but also like a sizable refactor, and I 
won't be upset if someone beats me to it. :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728



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


[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-07-19 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Pinging this. I believe all feedback from @EricWF was addressed back in my 
update to the patch in March.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282



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


[PATCH] D83611: [clang][NFC] Add 'override' keyword to virtual function overrides

2020-07-14 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D83611#2151278 , @dblaikie wrote:

> If you add/leave the "Differential Revision: https://reviews.llvm.org/D; 
> line in the commit message (arc will add this line automatically) Phabricator 
> will close the review for you automatically


Thanks--figured that out shortly after I did this one. :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83611/new/

https://reviews.llvm.org/D83611



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


[PATCH] D83611: [clang][NFC] Add 'override' keyword to virtual function overrides

2020-07-14 Thread Logan Smith via Phabricator via cfe-commits
logan-5 closed this revision.
logan-5 added a comment.

Committed as rG2c2a297bb6d1 



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83611/new/

https://reviews.llvm.org/D83611



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


[PATCH] D83616: [clang] Add 'override' to virtual function overrides generated by ClangAttrEmitter

2020-07-14 Thread Logan Smith via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGfbb30c31fefc: [clang] Add override to virtual 
function overrides generated by… (authored by logan-5).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83616/new/

https://reviews.llvm.org/D83616

Files:
  clang/utils/TableGen/ClangAttrEmitter.cpp


Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2012,10 +2012,10 @@
 return;
   // Generate a function that constructs a set of matching rules that describe
   // to which declarations the attribute should apply to.
-  OS << "virtual void getPragmaAttributeMatchRules("
+  OS << "void getPragmaAttributeMatchRules("
  << "llvm::SmallVectorImpl> , const LangOptions ) const {\n";
+ << ", bool>> , const LangOptions ) const override 
{\n";
   const Record *SubjectObj = Attr.getValueAsDef("Subjects");
   std::vector Subjects = 
SubjectObj->getValueAsListOfDefs("Subjects");
   for (const auto *Subject : Subjects) {
@@ -3519,8 +3519,8 @@
   // at all (for instance because it was applied to a type), or that the caller
   // has determined that the check should fail (perhaps prior to the creation
   // of the declaration).
-  OS << "virtual bool diagAppertainsToDecl(Sema , ";
-  OS << "const ParsedAttr , const Decl *D) const {\n";
+  OS << "bool diagAppertainsToDecl(Sema , ";
+  OS << "const ParsedAttr , const Decl *D) const override {\n";
   OS << "  if (";
   for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) {
 // If the subject has custom code associated with it, use the generated
@@ -3594,8 +3594,8 @@
   if (LangOpts.empty())
 return;
 
-  OS << "virtual bool diagLangOpts(Sema , const ParsedAttr ) ";
-  OS << "const {\n";
+  OS << "bool diagLangOpts(Sema , const ParsedAttr ) ";
+  OS << "const override {\n";
   OS << "  auto  = S.LangOpts;\n";
   OS << "  if (" << GenerateTestExpression(LangOpts) << ")\n";
   OS << "return true;\n\n";
@@ -3639,7 +3639,7 @@
   std::string Test;
   bool UsesT = GenerateTargetSpecificAttrChecks(R, Arches, Test, );
 
-  OS << "virtual bool existsInTarget(const TargetInfo ) const {\n";
+  OS << "bool existsInTarget(const TargetInfo ) const override {\n";
   if (UsesT)
 OS << "  const llvm::Triple  = Target.getTriple(); (void)T;\n";
   OS << "  return " << Test << ";\n";
@@ -3664,8 +3664,8 @@
   std::string Enum = CreateSemanticSpellings(Spellings, 
SemanticToSyntacticMap);
   std::string Name = Attr.getName().str() + "AttrSpellingMap";
 
-  OS << "virtual unsigned spellingIndexToSemanticSpelling(";
-  OS << "const ParsedAttr ) const {\n";
+  OS << "unsigned spellingIndexToSemanticSpelling(";
+  OS << "const ParsedAttr ) const override {\n";
   OS << Enum;
   OS << "  unsigned Idx = Attr.getAttributeSpellingListIndex();\n";
   WriteSemanticSpellingSwitch("Idx", SemanticToSyntacticMap, OS);
@@ -3678,8 +3678,8 @@
 return;
 
   // Generate a function which just converts from ParsedAttr to the Attr type.
-  OS << "virtual AttrHandling handleDeclAttribute(Sema , Decl *D,";
-  OS << "const ParsedAttr ) const {\n";
+  OS << "AttrHandling handleDeclAttribute(Sema , Decl *D,";
+  OS << "const ParsedAttr ) const override {\n";
   OS << "  D->addAttr(::new (S.Context) " << Attr.getName();
   OS << "Attr(S.Context, Attr));\n";
   OS << "  return AttributeApplied;\n";


Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2012,10 +2012,10 @@
 return;
   // Generate a function that constructs a set of matching rules that describe
   // to which declarations the attribute should apply to.
-  OS << "virtual void getPragmaAttributeMatchRules("
+  OS << "void getPragmaAttributeMatchRules("
  << "llvm::SmallVectorImpl> , const LangOptions ) const {\n";
+ << ", bool>> , const LangOptions ) const override {\n";
   const Record *SubjectObj = Attr.getValueAsDef("Subjects");
   std::vector Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
   for (const auto *Subject : Subjects) {
@@ -3519,8 +3519,8 @@
   // at all (for instance because it was applied to a type), or that the caller
   // has determined that the check should fail (perhaps prior to the creation
   // of the declaration).
-  OS << "virtual bool diagAppertainsToDecl(Sema , ";
-  OS << "const ParsedAttr , const Decl *D) const {\n";
+  OS << "bool diagAppertainsToDecl(Sema , ";
+  OS << "const ParsedAttr , const Decl *D) const override {\n";
   OS << "  if (";
   for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) {
 // If the subject has custom code associated with it, use the generated
@@ -3594,8 +3594,8 @@
   if (LangOpts.empty())
 return;
 
-  OS << "virtual 

[PATCH] D83616: [clang] Add 'override' to virtual function overrides generated by ClangAttrEmitter

2020-07-13 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Thanks! I would appreciate any help committing this.

I have a few of these kinds of NFC `override` patches in flight, and I'd love 
to be able to commit them myself and not bother people. I wonder what the 
process of gaining commit access looks like? I've been a contributor for about 
a year, with maybe a dozen or so patches landed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83616/new/

https://reviews.llvm.org/D83616



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


[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-12 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D82728#2146067 , @dblaikie wrote:

> Looks good - thanks for the patch and all the details! Might be worth turning 
> on by default in the LLVM build (after all the cleanup)


Thanks a lot! I don't (think I) have commit access yada yada, so I'd really 
appreciate any help getting this committed.

I've already got some of the cleanup in the works (D83611 
 and D83616 
), and was planning on taking care of the rest 
throughout the coming weekish. I'd be happy to turn this warning on in the LLVM 
build after that.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728



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


[PATCH] D83616: [clang] Add 'override' to virtual function overrides generated by ClangAttrEmitter

2020-07-10 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added reviewers: rsmith, aaron.ballman, john.brawn.
logan-5 added a project: clang.
Herald added a subscriber: cfe-commits.

ClangAttrEmitter.cpp generates `ParsedAttr` derived classes with virtual 
overrides in them (which end up in AttrParsedAttrImpl.inc); this patch ensures 
these generated functions are marked `override`, and not (redundantly) 
`virtual`.

I hesitate to say NFC since this does of course affect the behavior of the 
generator code, but the generated code behaves the same as it did before, so 
it's NFC in that sense.

These missing override sites were found by a Clang build equipped with 
-Wsuggest-override, as implemented in this patch 
 (D82728 ).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83616

Files:
  clang/utils/TableGen/ClangAttrEmitter.cpp


Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2012,10 +2012,10 @@
 return;
   // Generate a function that constructs a set of matching rules that describe
   // to which declarations the attribute should apply to.
-  OS << "virtual void getPragmaAttributeMatchRules("
+  OS << "void getPragmaAttributeMatchRules("
  << "llvm::SmallVectorImpl> , const LangOptions ) const {\n";
+ << ", bool>> , const LangOptions ) const override 
{\n";
   const Record *SubjectObj = Attr.getValueAsDef("Subjects");
   std::vector Subjects = 
SubjectObj->getValueAsListOfDefs("Subjects");
   for (const auto *Subject : Subjects) {
@@ -3519,8 +3519,8 @@
   // at all (for instance because it was applied to a type), or that the caller
   // has determined that the check should fail (perhaps prior to the creation
   // of the declaration).
-  OS << "virtual bool diagAppertainsToDecl(Sema , ";
-  OS << "const ParsedAttr , const Decl *D) const {\n";
+  OS << "bool diagAppertainsToDecl(Sema , ";
+  OS << "const ParsedAttr , const Decl *D) const override {\n";
   OS << "  if (";
   for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) {
 // If the subject has custom code associated with it, use the generated
@@ -3594,8 +3594,8 @@
   if (LangOpts.empty())
 return;
 
-  OS << "virtual bool diagLangOpts(Sema , const ParsedAttr ) ";
-  OS << "const {\n";
+  OS << "bool diagLangOpts(Sema , const ParsedAttr ) ";
+  OS << "const override {\n";
   OS << "  auto  = S.LangOpts;\n";
   OS << "  if (" << GenerateTestExpression(LangOpts) << ")\n";
   OS << "return true;\n\n";
@@ -3639,7 +3639,7 @@
   std::string Test;
   bool UsesT = GenerateTargetSpecificAttrChecks(R, Arches, Test, );
 
-  OS << "virtual bool existsInTarget(const TargetInfo ) const {\n";
+  OS << "bool existsInTarget(const TargetInfo ) const override {\n";
   if (UsesT)
 OS << "  const llvm::Triple  = Target.getTriple(); (void)T;\n";
   OS << "  return " << Test << ";\n";
@@ -3664,8 +3664,8 @@
   std::string Enum = CreateSemanticSpellings(Spellings, 
SemanticToSyntacticMap);
   std::string Name = Attr.getName().str() + "AttrSpellingMap";
 
-  OS << "virtual unsigned spellingIndexToSemanticSpelling(";
-  OS << "const ParsedAttr ) const {\n";
+  OS << "unsigned spellingIndexToSemanticSpelling(";
+  OS << "const ParsedAttr ) const override {\n";
   OS << Enum;
   OS << "  unsigned Idx = Attr.getAttributeSpellingListIndex();\n";
   WriteSemanticSpellingSwitch("Idx", SemanticToSyntacticMap, OS);
@@ -3678,8 +3678,8 @@
 return;
 
   // Generate a function which just converts from ParsedAttr to the Attr type.
-  OS << "virtual AttrHandling handleDeclAttribute(Sema , Decl *D,";
-  OS << "const ParsedAttr ) const {\n";
+  OS << "AttrHandling handleDeclAttribute(Sema , Decl *D,";
+  OS << "const ParsedAttr ) const override {\n";
   OS << "  D->addAttr(::new (S.Context) " << Attr.getName();
   OS << "Attr(S.Context, Attr));\n";
   OS << "  return AttributeApplied;\n";


Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2012,10 +2012,10 @@
 return;
   // Generate a function that constructs a set of matching rules that describe
   // to which declarations the attribute should apply to.
-  OS << "virtual void getPragmaAttributeMatchRules("
+  OS << "void getPragmaAttributeMatchRules("
  << "llvm::SmallVectorImpl> , const LangOptions ) const {\n";
+ << ", bool>> , const LangOptions ) const override {\n";
   const Record *SubjectObj = Attr.getValueAsDef("Subjects");
   std::vector Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
   for (const auto *Subject : Subjects) {
@@ -3519,8 +3519,8 @@
   // at all (for instance because it was applied to a type), or that the caller
   // has determined that the check should fail 

[PATCH] D83611: [clang][NFC] Add 'override' keyword to virtual function overrides

2020-07-10 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added a project: clang.
Herald added subscribers: cfe-commits, martong.

This patch adds `override` to several overriding virtual functions that were 
missing the keyword within the clang/ directory. NFC.

These were found by a Clang build equipped with `-Wsuggest-override`, as 
implemented in this patch  (D82728 
).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83611

Files:
  clang/include/clang/AST/DeclOpenMP.h
  clang/lib/AST/Interp/InterpFrame.h
  clang/lib/AST/OSLog.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp

Index: clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
@@ -58,7 +58,7 @@
  PointerEscapeKind Kind) const;
 
   void printState(raw_ostream , ProgramStateRef State,
-  const char *NL, const char *Sep) const;
+  const char *NL, const char *Sep) const override;
 };
 } // end anonymous namespace
 
Index: clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
@@ -57,7 +57,7 @@
   Callback(const NumberObjectConversionChecker *C,
BugReporter , AnalysisDeclContext *ADC)
   : C(C), BR(BR), ADC(ADC) {}
-  virtual void run(const MatchFinder::MatchResult );
+  void run(const MatchFinder::MatchResult ) override;
 };
 } // end of anonymous namespace
 
Index: clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -66,7 +66,7 @@
   ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
  bool Assumption) const;
   void printState(raw_ostream , ProgramStateRef State,
-  const char *NL, const char *Sep) const;
+  const char *NL, const char *Sep) const override;
 
 private:
   typedef std::pair AllocationPair;
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1066,7 +1066,7 @@
 TemplateArgumentListInfo 
 ICEDiagnoser(LookupResult , TemplateArgumentListInfo )
 : R(R), Args(Args) {}
-void diagnoseNotICE(Sema , SourceLocation Loc, SourceRange SR) {
+void diagnoseNotICE(Sema , SourceLocation Loc, SourceRange SR) override {
   S.Diag(Loc, diag::err_decomp_decl_std_tuple_size_not_constant)
   << printTemplateArgs(S.Context.getPrintingPolicy(), Args);
 }
Index: clang/lib/Basic/Targets/OSTargets.h
===
--- clang/lib/Basic/Targets/OSTargets.h
+++ clang/lib/Basic/Targets/OSTargets.h
@@ -821,7 +821,7 @@
 : public OSTargetInfo {
 protected:
   void getOSDefines(const LangOptions , const llvm::Triple ,
-MacroBuilder ) const {
+MacroBuilder ) const override {
 // A common platform macro.
 if (Opts.POSIXThreads)
   Builder.defineMacro("_REENTRANT");
Index: clang/lib/AST/OSLog.cpp
===
--- clang/lib/AST/OSLog.cpp
+++ clang/lib/AST/OSLog.cpp
@@ -55,9 +55,9 @@
 ArgsData.reserve(Args.size());
   }
 
-  virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier ,
- const char *StartSpecifier,
- unsigned SpecifierLen) {
+  bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier ,
+ const char *StartSpecifier,
+ unsigned SpecifierLen) override {
 if (!FS.consumesDataArgument() &&
 FS.getConversionSpecifier().getKind() !=
 clang::analyze_format_string::ConversionSpecifier::PrintErrno)
Index: clang/lib/AST/Interp/InterpFrame.h
===
--- clang/lib/AST/Interp/InterpFrame.h
+++ clang/lib/AST/Interp/InterpFrame.h
@@ -45,16 +45,16 @@
   void popArgs();
 
   /// Describes the frame with arguments for diagnostic purposes.
-  void describe(llvm::raw_ostream );
+  void describe(llvm::raw_ostream ) override;
 
   /// Returns the parent 

[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-09 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Feels like a dumb question, but I'm not sure if and how those build failures 
are related to this patch? They seem to involve completely separate parts of 
the LLVM project (and `.c` files to boot). Was it that the build was failing 
for an unrelated reason at the moment the bots happened to build this patch? Or 
am I misunderstanding something more obvious?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728



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


[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked an inline comment as done.
logan-5 added inline comments.



Comment at: clang/test/SemaCXX/warn-suggest-destructor-override:1
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify 
-Wsuggest-destructor-override
+

logan-5 wrote:
> dblaikie wrote:
> > Does GCC have suggest-destructor-override as a separate warning too?
> It does not. In fact, there's no way to get GCC to warn about destructors 
> missing `override`. (Which is somewhat defensible, since `override` is really 
> great for preventing subtle signature mismatches/typos, but destructors don't 
> really have those problems.) However, Clang already has a destructor-specific 
> flavor of the inconsistent-override warning, so I added 
> -Wsuggest-destructor-override for symmetry with 
> -Winconsistent-missing-[destructor-]override.
Note that this really is the best of both worlds, since it lets Clang's 
-Wsuggest-override behave identically to GCC's (not warning on destructors), as 
well as be consistent with its own already existing override warnings (with a 
special extra flag to enable warnings for destructors).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728



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


[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked an inline comment as done.
logan-5 added inline comments.



Comment at: clang/test/SemaCXX/warn-suggest-destructor-override:1
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify 
-Wsuggest-destructor-override
+

dblaikie wrote:
> Does GCC have suggest-destructor-override as a separate warning too?
It does not. In fact, there's no way to get GCC to warn about destructors 
missing `override`. (Which is somewhat defensible, since `override` is really 
great for preventing subtle signature mismatches/typos, but destructors don't 
really have those problems.) However, Clang already has a destructor-specific 
flavor of the inconsistent-override warning, so I added 
-Wsuggest-destructor-override for symmetry with 
-Winconsistent-missing-[destructor-]override.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728



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


[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 276248.
logan-5 added a comment.

Fall back to -Wsuggest-override if -Winconsistent-missing-override is disabled.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/warn-suggest-destructor-override
  clang/test/SemaCXX/warn-suggest-override

Index: clang/test/SemaCXX/warn-suggest-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-override
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-override
+
+struct A {
+  ~A();
+  void run();
+};
+
+struct B : public A {
+  ~B();
+  void run();
+};
+
+struct C {
+  virtual void run(); // expected-note 2{{overridden virtual function is here}}
+  virtual ~C();
+};
+
+struct D : public C {
+  void run();
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  ~D();
+};
+
+struct E : public C {
+  virtual void run();
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  virtual ~E();
+};
+
+struct F : public C {
+  void run() override;
+  ~F() override;
+};
+
+struct G : public C {
+  void run() final;
+  ~G() final;
+};
Index: clang/test/SemaCXX/warn-suggest-destructor-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-destructor-override
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-destructor-override
+
+struct A {
+  ~A();
+  virtual void run();
+};
+
+struct B : public A {
+  ~B();
+};
+
+struct C {
+  virtual void run();
+  virtual ~C();  // expected-note 2{{overridden virtual function is here}}
+};
+
+struct D : public C {
+  void run();
+  ~D();
+  // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}}
+};
+
+struct E : public C {
+  void run();
+  virtual ~E();
+  // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}}
+};
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3045,7 +3045,7 @@
   << MD->getDeclName();
 }
 
-void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) {
+void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent) {
   if (D->isInvalidDecl() || D->hasAttr())
 return;
   CXXMethodDecl *MD = dyn_cast(D);
@@ -3061,12 +3061,22 @@
   return;
 
   if (MD->size_overridden_methods() > 0) {
-unsigned DiagID = isa(MD)
-  ? diag::warn_destructor_marked_not_override_overriding
-  : diag::warn_function_marked_not_override_overriding;
-Diag(MD->getLocation(), DiagID) << MD->getDeclName();
-const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
-Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+auto EmitDiag = [&](unsigned DiagInconsistent, unsigned DiagSuggest) {
+  unsigned DiagID =
+  Inconsistent && !Diags.isIgnored(DiagInconsistent, MD->getLocation())
+  ? DiagInconsistent
+  : DiagSuggest;
+  Diag(MD->getLocation(), DiagID) << MD->getDeclName();
+  const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
+  Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+};
+if (isa(MD))
+  EmitDiag(
+  diag::warn_inconsistent_destructor_marked_not_override_overriding,
+  diag::warn_suggest_destructor_marked_not_override_overriding);
+else
+  EmitDiag(diag::warn_inconsistent_function_marked_not_override_overriding,
+   diag::warn_suggest_function_marked_not_override_overriding);
   }
 }
 
@@ -6749,13 +6759,10 @@
 }
   }
 
-  if (HasMethodWithOverrideControl &&
-  HasOverridingMethodWithoutOverrideControl) {
-// At least one method has the 'override' control declared.
-// Diagnose all other overridden methods which do not have 'override'
-// specified on them.
+  if (HasOverridingMethodWithoutOverrideControl) {
+bool HasInconsistentOverrideControl = HasMethodWithOverrideControl;
 for (auto *M : Record->methods())
-  DiagnoseAbsenceOfOverrideControl(M);
+  DiagnoseAbsenceOfOverrideControl(M, HasInconsistentOverrideControl);
   }
 
   // Check the defaulted secondary comparisons after any other member functions.
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -6961,7 +6961,7 @@
 
   /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was
   /// 

[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D82728#2137492 , @dblaikie wrote:

> Oh, yep, there's a way - it's usually used for performance-costly warnings, 
> to not spend the resources computing the warning if it's disabled anyway.


Wow, thanks--overlooked that in a big way. That'll definitely solve the 
problem. Fixed up patch on the way.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728



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


[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 276187.
logan-5 added a comment.

Addressed minor feedback.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/warn-suggest-destructor-override
  clang/test/SemaCXX/warn-suggest-override

Index: clang/test/SemaCXX/warn-suggest-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-override
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-override
+
+struct A {
+  ~A();
+  void run();
+};
+
+struct B : public A {
+  ~B();
+  void run();
+};
+
+struct C {
+  virtual void run(); // expected-note 2{{overridden virtual function is here}}
+  virtual ~C();
+};
+
+struct D : public C {
+  void run();
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  ~D();
+};
+
+struct E : public C {
+  virtual void run();
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  virtual ~E();
+};
+
+struct F : public C {
+  void run() override;
+  ~F() override;
+};
+
+struct G : public C {
+  void run() final;
+  ~G() final;
+};
Index: clang/test/SemaCXX/warn-suggest-destructor-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-destructor-override
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-destructor-override
+
+struct A {
+  ~A();
+  virtual void run();
+};
+
+struct B : public A {
+  ~B();
+};
+
+struct C {
+  virtual void run();
+  virtual ~C();  // expected-note 2{{overridden virtual function is here}}
+};
+
+struct D : public C {
+  void run();
+  ~D();
+  // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}}
+};
+
+struct E : public C {
+  void run();
+  virtual ~E();
+  // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}}
+};
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3045,7 +3045,7 @@
   << MD->getDeclName();
 }
 
-void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) {
+void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent) {
   if (D->isInvalidDecl() || D->hasAttr())
 return;
   CXXMethodDecl *MD = dyn_cast(D);
@@ -3061,12 +3061,19 @@
   return;
 
   if (MD->size_overridden_methods() > 0) {
-unsigned DiagID = isa(MD)
-  ? diag::warn_destructor_marked_not_override_overriding
-  : diag::warn_function_marked_not_override_overriding;
-Diag(MD->getLocation(), DiagID) << MD->getDeclName();
-const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
-Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+auto EmitDiag = [&](unsigned DiagDtor, unsigned DiagFn) {
+  unsigned DiagID = isa(MD) ? DiagDtor : DiagFn;
+  Diag(MD->getLocation(), DiagID) << MD->getDeclName();
+  const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
+  Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+};
+if (Inconsistent)
+  EmitDiag(
+  diag::warn_inconsistent_destructor_marked_not_override_overriding,
+  diag::warn_inconsistent_function_marked_not_override_overriding);
+else
+  EmitDiag(diag::warn_suggest_destructor_marked_not_override_overriding,
+   diag::warn_suggest_function_marked_not_override_overriding);
   }
 }
 
@@ -6749,13 +6756,10 @@
 }
   }
 
-  if (HasMethodWithOverrideControl &&
-  HasOverridingMethodWithoutOverrideControl) {
-// At least one method has the 'override' control declared.
-// Diagnose all other overridden methods which do not have 'override'
-// specified on them.
+  if (HasOverridingMethodWithoutOverrideControl) {
+bool HasInconsistentOverrideControl = HasMethodWithOverrideControl;
 for (auto *M : Record->methods())
-  DiagnoseAbsenceOfOverrideControl(M);
+  DiagnoseAbsenceOfOverrideControl(M, HasInconsistentOverrideControl);
   }
 
   // Check the defaulted secondary comparisons after any other member functions.
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -6961,7 +6961,7 @@
 
   /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was
   /// not used in the declaration of an overriding method.
-  void DiagnoseAbsenceOfOverrideControl(NamedDecl *D);
+  void DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool 

[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked 2 inline comments as done.
logan-5 added a comment.

In D82728#2137021 , @dblaikie wrote:

> I think it might be nice to make the -Wno-inconsistent-missing-override 
> -Wsuggest-override situation a bit better (by having it still do the same 
> thing as -Wsuggest-override) but I don't feel /too/ strongly about it.


So, ironing this out would mean the code would need this structure:

  if (Inconsistent && IsWarningEnabled(-Winconsistent-missing-override))
  Emit(-Winconsistent-missing-override);
  else
  Emit(-Wsuggest-override);

The issue is that I wasn't able to find a way to ask if a warning is enabled 
and make a control flow decision based on that. If there is an API for doing 
this, it's hidden well. :) So I fell back to just doing `if (Inconsistent)` 
instead, which has this quirk if the inconsistent version of the warning is 
disabled.




Comment at: clang/lib/Sema/SemaDeclCXX.cpp:3064
   if (MD->size_overridden_methods() > 0) {
-unsigned DiagID = isa(MD)
-  ? 
diag::warn_destructor_marked_not_override_overriding
-  : diag::warn_function_marked_not_override_overriding;
-Diag(MD->getLocation(), DiagID) << MD->getDeclName();
-const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
-Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+auto EmitDiag = [this, MD](unsigned DiagDtor, unsigned DiagFn) {
+  unsigned DiagID = isa(MD) ? DiagDtor : DiagFn;

dblaikie wrote:
> Generally I'd recommend default ref capture `[&]` on any lambda that doesn't 
> escape its scope - normal scopes don't need to document which variables you 
> use inside them, and I think the same applies to lambdas (bit more debatable 
> when the lambda is named and called later, even within the same scope - so if 
> you feel strongly about keeping it the way it is, that's OK)
I don't feel strongly at all; I'm fine with `[&]`. I'll make that change.



Comment at: clang/test/SemaCXX/warn-suggest-override:3-4
+
+class A {
+ public:
+  ~A() {}

dblaikie wrote:
> I'd probably simplify these tests by using struct, so everything's implicitly 
> public, rather than class and having to make things public.
> 
> Also probably member function declarations rather than definitions would be 
> simpler?
Can do.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728



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


[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 276162.
logan-5 added a comment.

clang-formatted the diff.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/warn-suggest-destructor-override
  clang/test/SemaCXX/warn-suggest-override

Index: clang/test/SemaCXX/warn-suggest-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-override
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-override
+
+class A {
+ public:
+  ~A() {}
+  void run() {}
+};
+
+class B : public A {
+ public:
+  ~B() {}
+  void run() {}
+};
+
+class C {
+ public:
+  virtual void run() {} // expected-note 2{{overridden virtual function is here}}
+  virtual ~C() {}
+};
+
+class D : public C {
+ public:
+  void run() {}
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  ~D() {}
+};
+
+class E : public C {
+ public:
+  virtual void run() {}
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  virtual ~E() {}
+};
+
+class F : public C {
+ public:
+  void run() override {}
+  ~F() override {}
+};
+
+class G : public C {
+ public:
+  void run() final {}
+  ~G() final {}
+};
Index: clang/test/SemaCXX/warn-suggest-destructor-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-destructor-override
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-destructor-override
+
+class A {
+ public:
+  ~A() {}
+  virtual void run() {}
+};
+
+class B : public A {
+ public:
+  ~B() {}
+};
+
+class C {
+ public:
+  virtual void run() {}
+  virtual ~C() {}  // expected-note 2{{overridden virtual function is here}}
+};
+
+class D : public C {
+ public:
+  void run() {}
+  ~D() {}
+  // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}}
+};
+
+class E : public C {
+ public:
+  void run() {}
+  virtual ~E() {}
+  // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}}
+};
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3045,7 +3045,7 @@
   << MD->getDeclName();
 }
 
-void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) {
+void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent) {
   if (D->isInvalidDecl() || D->hasAttr())
 return;
   CXXMethodDecl *MD = dyn_cast(D);
@@ -3061,12 +3061,19 @@
   return;
 
   if (MD->size_overridden_methods() > 0) {
-unsigned DiagID = isa(MD)
-  ? diag::warn_destructor_marked_not_override_overriding
-  : diag::warn_function_marked_not_override_overriding;
-Diag(MD->getLocation(), DiagID) << MD->getDeclName();
-const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
-Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+auto EmitDiag = [this, MD](unsigned DiagDtor, unsigned DiagFn) {
+  unsigned DiagID = isa(MD) ? DiagDtor : DiagFn;
+  Diag(MD->getLocation(), DiagID) << MD->getDeclName();
+  const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
+  Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+};
+if (Inconsistent)
+  EmitDiag(
+  diag::warn_inconsistent_destructor_marked_not_override_overriding,
+  diag::warn_inconsistent_function_marked_not_override_overriding);
+else
+  EmitDiag(diag::warn_suggest_destructor_marked_not_override_overriding,
+   diag::warn_suggest_function_marked_not_override_overriding);
   }
 }
 
@@ -6749,13 +6756,10 @@
 }
   }
 
-  if (HasMethodWithOverrideControl &&
-  HasOverridingMethodWithoutOverrideControl) {
-// At least one method has the 'override' control declared.
-// Diagnose all other overridden methods which do not have 'override'
-// specified on them.
+  if (HasOverridingMethodWithoutOverrideControl) {
+bool HasInconsistentOverrideControl = HasMethodWithOverrideControl;
 for (auto *M : Record->methods())
-  DiagnoseAbsenceOfOverrideControl(M);
+  DiagnoseAbsenceOfOverrideControl(M, HasInconsistentOverrideControl);
   }
 
   // Check the defaulted secondary comparisons after any other member functions.
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -6961,7 +6961,7 @@
 
   /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was
   /// not used in the 

[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D82728#2135149 , @dblaikie wrote:

> Is the implementation you're proposing fairly consistent with GCC's? Run it 
> over any big codebases to check it warns in the same places GCC does?


This patch has the same behavior as `-Wsuggest-override` in GCC >= 9. In GCC 
<9, it would suggest adding `override` to `void foo() final`, but in GCC >=9, 
`final` is enough to suppress the warning. This patch's `-Wsuggest-override`, 
as well as Clang's pre-existing `-Winconsistent-missing-override`, are also 
silenced by `final`. (https://godbolt.org/z/hbxLK6)

I built Clang itself with a Clang that had this patch, and with GCC with 
`-Wsuggest-override`, and compared the results--they were identical (except for 
the warning text). (618 warnings, for those interested.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728



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


[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Glad this is generating some discussion. For my $0.02, I would also (obviously) 
love to be able to enable this warning on all the codebases I work on, and this 
patch was born out of a discussion on the C++ Slack with another user who had 
found this warning very useful in GCC and was wondering why Clang didn't have 
it yet.

In D82728#2134072 , @dblaikie wrote:

> The issue is that such a warning then needs to be off by default, because we 
> can't assume the user's intent. And Clang's historically been fairly averse 
> to off-by-default warnings due to low user-penetration (not zero, like I 
> said, I imagine LLVM itself would use such a warning, were it implemented) & 
> so concerns about the cost/benefit tradeoff of the added complexity (source 
> code and runtime) of the feature.


I agree `-Wsuggest-override` should be off by default, yet I suspect its 
user-penetration will be much higher than other off-by-default warnings, due to 
numerous instances of people on the Internet asking for 
 this feature 
, as well as the precedent for it 
set by GCC. Moreover, since this implementation of this warning lies along the 
exact same code paths as the already existing 
`-Winconsistent-missing-override`, the added complexity from this patch is 
absolutely minimal.




Comment at: clang/lib/Sema/SemaDeclCXX.cpp:3075
+  : diag::
+warn_inconsistent_function_marked_not_override_overriding);
+else

Quuxplusone wrote:
> These linebreaks are super unfortunate. Could they be improved by doing it 
> like this?
> ```
> auto EmitDiag = [this, MD](unsigned DiagDtor, unsigned DiagFn) {
>   unsigned DiagID = isa(MD) ? DiagDtor : DiagFn;
>   Diag(MD->getLocation(), DiagID) << MD->getDeclName();
>   const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
>   Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
> };
> if (Inconsistent)
>   
> EmitDiag(diag::warn_inconsistent_destructor_marked_not_override_overriding,
>
> diag::warn_inconsistent_function_marked_not_override_overriding);
> else
>   EmitDiag(diag::warn_suggest_destructor_marked_not_override_overriding
>diag::warn_suggest_function_marked_not_override_overriding);
> ```
Agreed. Good idea on the fix--needed one more line break (the first one still 
hit column 81), but it looks much better now.



Comment at: clang/test/SemaCXX/warn-suggest-destructor-override:6
+  ~A() {}
+  void virtual run() {}
+};

Quuxplusone wrote:
> Surely this doesn't compile?!
Because of `void virtual`? It does, surprisingly, as it does in the test for 
warn-inconsistent-missing-destructor-override, where I pilfered this from.

Nevertheless, changed to `virtual void` for sanity's sake.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728



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


[PATCH] D82728: [clang] Add -Wsuggest-override

2020-07-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 275928.
logan-5 marked 6 inline comments as done.
logan-5 added a comment.

Addressed some feedback.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/warn-suggest-destructor-override
  clang/test/SemaCXX/warn-suggest-override

Index: clang/test/SemaCXX/warn-suggest-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-override
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-override
+
+class A {
+ public:
+  ~A() {}
+  void run() {}
+};
+
+class B : public A {
+ public:
+  ~B() {}
+  void run() {}
+};
+
+class C {
+ public:
+  virtual void run() {} // expected-note 2{{overridden virtual function is here}}
+  virtual ~C() {}
+};
+
+class D : public C {
+ public:
+  void run() {}
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  ~D() {}
+};
+
+class E : public C {
+ public:
+  virtual void run() {}
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  virtual ~E() {}
+};
+
+class F : public C {
+ public:
+  void run() override {}
+  ~F() override {}
+};
+
+class G : public C {
+ public:
+  void run() final {}
+  ~G() final {}
+};
Index: clang/test/SemaCXX/warn-suggest-destructor-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-destructor-override
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-destructor-override
+
+class A {
+ public:
+  ~A() {}
+  virtual void run() {}
+};
+
+class B : public A {
+ public:
+  ~B() {}
+};
+
+class C {
+ public:
+  virtual void run() {}
+  virtual ~C() {}  // expected-note 2{{overridden virtual function is here}}
+};
+
+class D : public C {
+ public:
+  void run() {}
+  ~D() {}
+  // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}}
+};
+
+class E : public C {
+ public:
+  void run() {}
+  virtual ~E() {}
+  // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}}
+};
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3045,7 +3045,7 @@
   << MD->getDeclName();
 }
 
-void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) {
+void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent) {
   if (D->isInvalidDecl() || D->hasAttr())
 return;
   CXXMethodDecl *MD = dyn_cast(D);
@@ -3061,12 +3061,20 @@
   return;
 
   if (MD->size_overridden_methods() > 0) {
-unsigned DiagID = isa(MD)
-  ? diag::warn_destructor_marked_not_override_overriding
-  : diag::warn_function_marked_not_override_overriding;
-Diag(MD->getLocation(), DiagID) << MD->getDeclName();
-const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
-Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+auto EmitDiag = [this, MD](unsigned DiagDtor, unsigned DiagFn) {
+  unsigned DiagID = isa(MD) ? DiagDtor : DiagFn;
+  Diag(MD->getLocation(), DiagID) << MD->getDeclName();
+  const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
+  Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+};
+if (Inconsistent)
+  EmitDiag(
+  diag::warn_inconsistent_destructor_marked_not_override_overriding,
+  diag::warn_inconsistent_function_marked_not_override_overriding);
+else
+  EmitDiag(
+  diag::warn_suggest_destructor_marked_not_override_overriding,
+  diag::warn_suggest_function_marked_not_override_overriding);
   }
 }
 
@@ -6749,13 +6757,10 @@
 }
   }
 
-  if (HasMethodWithOverrideControl &&
-  HasOverridingMethodWithoutOverrideControl) {
-// At least one method has the 'override' control declared.
-// Diagnose all other overridden methods which do not have 'override'
-// specified on them.
+  if (HasOverridingMethodWithoutOverrideControl) {
+bool HasInconsistentOverrideControl = HasMethodWithOverrideControl;
 for (auto *M : Record->methods())
-  DiagnoseAbsenceOfOverrideControl(M);
+  DiagnoseAbsenceOfOverrideControl(M, HasInconsistentOverrideControl);
   }
 
   // Check the defaulted secondary comparisons after any other member functions.
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -6961,7 +6961,7 @@
 
   /// DiagnoseAbsenceOfOverrideControl - Diagnose if 

[PATCH] D82728: [clang] Add -Wsuggest-override

2020-06-29 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 273991.
logan-5 added a comment.

Don't warn for destructors by default. This makes 
-Wsuggest-[destructor-]override more consistent with the behavior of 
-Winconsistent-missing-[destructor-]override, as well as gcc.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/warn-suggest-destructor-override
  clang/test/SemaCXX/warn-suggest-override

Index: clang/test/SemaCXX/warn-suggest-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-override
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-override
+
+class A {
+ public:
+  ~A() {}
+  void run() {}
+};
+
+class B : public A {
+ public:
+  ~B() {}
+  void run() {}
+};
+
+class C {
+ public:
+  virtual void run() {} // expected-note 2{{overridden virtual function is here}}
+  virtual ~C() {}
+};
+
+class D : public C {
+ public:
+  void run() {}
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  ~D() {}
+};
+
+class E : public C {
+ public:
+  virtual void run() {}
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  virtual ~E() {}
+};
+
+class F : public C {
+ public:
+  void run() override {}
+  ~F() override {}
+};
+
+class G : public C {
+ public:
+  void run() final {}
+  ~G() final {}
+};
Index: clang/test/SemaCXX/warn-suggest-destructor-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-destructor-override
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-destructor-override
+
+class A {
+ public:
+  ~A() {}
+  void virtual run() {}
+};
+
+class B : public A {
+ public:
+  ~B() {}
+};
+
+class C {
+ public:
+  virtual void run() {}
+  virtual ~C() {}  // expected-note 2{{overridden virtual function is here}}
+};
+
+class D : public C {
+ public:
+  void run() {}
+  ~D() {}
+  // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}}
+};
+
+class E : public C {
+ public:
+  void run() {}
+  virtual ~E() {}
+  // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}}
+};
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3045,7 +3045,7 @@
   << MD->getDeclName();
 }
 
-void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) {
+void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent) {
   if (D->isInvalidDecl() || D->hasAttr())
 return;
   CXXMethodDecl *MD = dyn_cast(D);
@@ -3061,12 +3061,23 @@
   return;
 
   if (MD->size_overridden_methods() > 0) {
-unsigned DiagID = isa(MD)
-  ? diag::warn_destructor_marked_not_override_overriding
-  : diag::warn_function_marked_not_override_overriding;
-Diag(MD->getLocation(), DiagID) << MD->getDeclName();
-const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
-Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+auto EmitDiag = [this, MD](unsigned DiagID) {
+  Diag(MD->getLocation(), DiagID) << MD->getDeclName();
+  const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
+  Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+};
+if (Inconsistent)
+  EmitDiag(
+  isa(MD)
+  ? diag::
+warn_inconsistent_destructor_marked_not_override_overriding
+  : diag::
+warn_inconsistent_function_marked_not_override_overriding);
+else
+  EmitDiag(
+  isa(MD)
+  ? diag::warn_suggest_destructor_marked_not_override_overriding
+  : diag::warn_suggest_function_marked_not_override_overriding);
   }
 }
 
@@ -6749,13 +6760,10 @@
 }
   }
 
-  if (HasMethodWithOverrideControl &&
-  HasOverridingMethodWithoutOverrideControl) {
-// At least one method has the 'override' control declared.
-// Diagnose all other overridden methods which do not have 'override'
-// specified on them.
+  if (HasOverridingMethodWithoutOverrideControl) {
+bool InconsistentOverrideControl = HasMethodWithOverrideControl;
 for (auto *M : Record->methods())
-  DiagnoseAbsenceOfOverrideControl(M);
+  DiagnoseAbsenceOfOverrideControl(M, InconsistentOverrideControl);
   }
 
   // Check the defaulted secondary comparisons after any other member functions.
Index: clang/include/clang/Sema/Sema.h
===
--- 

[PATCH] D82728: [clang] Add -Wsuggest-override

2020-06-29 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 273986.
logan-5 added a comment.

Ran clang-format over the diff.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82728/new/

https://reviews.llvm.org/D82728

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/warn-suggest-destructor-override
  clang/test/SemaCXX/warn-suggest-override

Index: clang/test/SemaCXX/warn-suggest-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-override
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-override
+
+class A {
+ public:
+  ~A() {}
+  void run() {}
+};
+
+class B : public A {
+ public:
+  ~B() {}
+  void run() {}
+};
+
+class C {
+ public:
+  virtual void run() {} // expected-note 2{{overridden virtual function is here}}
+  virtual ~C() {}  // expected-note 2{{overridden virtual function is here}}
+};
+
+class D : public C {
+ public:
+  void run() {}
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  ~D() {}
+  // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}}
+};
+
+class E : public C {
+ public:
+  virtual void run() {}
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  virtual ~E() {}
+  // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}}
+};
+
+class F : public C {
+ public:
+  void run() override {}
+  ~F() override {}
+};
+
+class G : public C {
+ public:
+  void run() final {}
+  ~G() final {}
+};
Index: clang/test/SemaCXX/warn-suggest-destructor-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-destructor-override
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-destructor-override
+
+class A {
+ public:
+  ~A() {}
+  void virtual run() {}
+};
+
+class B : public A {
+ public:
+  ~B() {}
+};
+
+class C {
+ public:
+  virtual void run() {}
+  virtual ~C() {}  // expected-note 2{{overridden virtual function is here}}
+};
+
+class D : public C {
+ public:
+  void run() {}
+  ~D() {}
+  // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}}
+};
+
+class E : public C {
+ public:
+  void run() {}
+  virtual ~E() {}
+  // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}}
+};
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3045,7 +3045,7 @@
   << MD->getDeclName();
 }
 
-void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) {
+void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent) {
   if (D->isInvalidDecl() || D->hasAttr())
 return;
   CXXMethodDecl *MD = dyn_cast(D);
@@ -3061,12 +3061,23 @@
   return;
 
   if (MD->size_overridden_methods() > 0) {
-unsigned DiagID = isa(MD)
-  ? diag::warn_destructor_marked_not_override_overriding
-  : diag::warn_function_marked_not_override_overriding;
-Diag(MD->getLocation(), DiagID) << MD->getDeclName();
-const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
-Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+auto EmitDiag = [this, MD](unsigned DiagID) {
+  Diag(MD->getLocation(), DiagID) << MD->getDeclName();
+  const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
+  Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+};
+if (Inconsistent)
+  EmitDiag(
+  isa(MD)
+  ? diag::
+warn_inconsistent_destructor_marked_not_override_overriding
+  : diag::
+warn_inconsistent_function_marked_not_override_overriding);
+else
+  EmitDiag(
+  isa(MD)
+  ? diag::warn_suggest_destructor_marked_not_override_overriding
+  : diag::warn_suggest_function_marked_not_override_overriding);
   }
 }
 
@@ -6749,13 +6760,10 @@
 }
   }
 
-  if (HasMethodWithOverrideControl &&
-  HasOverridingMethodWithoutOverrideControl) {
-// At least one method has the 'override' control declared.
-// Diagnose all other overridden methods which do not have 'override'
-// specified on them.
+  if (HasOverridingMethodWithoutOverrideControl) {
+bool InconsistentOverrideControl = HasMethodWithOverrideControl;
 for (auto *M : Record->methods())
-  DiagnoseAbsenceOfOverrideControl(M);
+  DiagnoseAbsenceOfOverrideControl(M, InconsistentOverrideControl);
   }
 
   // Check the defaulted secondary comparisons after any other member functions.
Index: 

[PATCH] D82728: [clang] Add -Wsuggest-override

2020-06-29 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added a reviewer: rsmith.
logan-5 added a project: clang.
Herald added a subscriber: cfe-commits.

This patch adds `-Wsuggest-override`, which allows for more aggressive 
enforcement of modern C++ best practices, as well as better compatibility with 
gcc, which has had its own `-Wsuggest-override` since version 5.1.

Clang already has `-Winconsistent-missing-override`, which only warns in the 
case where there is at least one function already marked `override` in a class. 
This warning strengthens that warning by suggesting the `override` keyword 
regardless of whether it is already present anywhere.

The text between suggest-override and inconsistent-missing-override is now 
shared, using `TextSubstitution` for the entire diagnostic text. I'm not sure 
if there is a better way to accomplish this.

This patch as written behaves strangely with 
`-Wno-inconsistent-missing-override -Wsuggest-override`. In that case, a 
warning is //only// generated if there are no overrides already marked (because 
inconsistent-missing-override 'wins' when choosing which diagnostic to emit). 
However, this is a fairly nonsensical use case, so in my opinion it's fine.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D82728

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/warn-suggest-destructor-override
  clang/test/SemaCXX/warn-suggest-override

Index: clang/test/SemaCXX/warn-suggest-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-override
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-override
+
+class A {
+ public:
+  ~A() {}
+  void run() {}
+};
+
+class B : public A {
+ public:
+  ~B() {}
+  void run() {}
+};
+
+class C {
+ public:
+  virtual void run() {} // expected-note 2{{overridden virtual function is here}}
+  virtual ~C() {}  // expected-note 2{{overridden virtual function is here}}
+};
+
+class D : public C {
+ public:
+  void run() {}
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  ~D() {}
+  // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}}
+};
+
+class E : public C {
+ public:
+  virtual void run() {}
+  // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}}
+  virtual ~E() {}
+  // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}}
+};
+
+class F : public C {
+ public:
+  void run() override {}
+  ~F() override {}
+};
+
+class G : public C {
+ public:
+  void run() final {}
+  ~G() final {}
+};
Index: clang/test/SemaCXX/warn-suggest-destructor-override
===
--- /dev/null
+++ clang/test/SemaCXX/warn-suggest-destructor-override
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-destructor-override
+
+class A {
+ public:
+  ~A() {}
+  void virtual run() {}
+};
+
+class B : public A {
+ public:
+  ~B() {}
+};
+
+class C {
+ public:
+  virtual void run() {}
+  virtual ~C() {}  // expected-note 2{{overridden virtual function is here}}
+};
+
+class D : public C {
+ public:
+  void run() {}
+  ~D() {}
+  // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}}
+};
+
+class E : public C {
+ public:
+  void run() {}
+  virtual ~E() {}
+  // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}}
+};
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3045,7 +3045,7 @@
   << MD->getDeclName();
 }
 
-void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) {
+void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent) {
   if (D->isInvalidDecl() || D->hasAttr())
 return;
   CXXMethodDecl *MD = dyn_cast(D);
@@ -3061,12 +3061,19 @@
   return;
 
   if (MD->size_overridden_methods() > 0) {
-unsigned DiagID = isa(MD)
-  ? diag::warn_destructor_marked_not_override_overriding
-  : diag::warn_function_marked_not_override_overriding;
-Diag(MD->getLocation(), DiagID) << MD->getDeclName();
-const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
-Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+auto EmitDiag = [this, MD](unsigned DiagID) {
+  Diag(MD->getLocation(), DiagID) << MD->getDeclName();
+  const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
+  Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
+};
+if (Inconsistent)
+  EmitDiag(isa(MD)
+  ? diag::warn_inconsistent_destructor_marked_not_override_overriding
+ 

[PATCH] D74238: [clang] Improve diagnostic note for implicit conversion sequences that would work if more than one implicit user-defined conversion were allowed.

2020-05-05 Thread Logan Smith via Phabricator via cfe-commits
logan-5 abandoned this revision.
logan-5 added a comment.

@rsmith the intention is to only speculatively search one level deep (e.g. 
search for chains like A->B, B->C, but no deeper), which should cover most of 
the cases that are surprising to users.

However, the implementation of this patch has some issues, and it doesn't work 
quite how I intended. I still like the idea and I'd like to revisit it, but 
pondering how to get it to work properly is more than I have time for at the 
moment, with all the craziness in the world. So in the meantime, I'd like to 
withdraw it--I'll mark it and its related patches as 'abandoned'. Thanks very 
much for your time considering it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74238/new/

https://reviews.llvm.org/D74238



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


[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-03-13 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 250272.
logan-5 marked 2 inline comments as done.
logan-5 added a comment.

Re-juggled and made `bool OnlyDependsOnFundamentalArraySizes(QualType QualTy)` 
recursive. Made `::` assert more useful. Thanks @Quuxplusone for both good 
ideas.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-generic-lambdas.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-operators.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
@@ -0,0 +1,332 @@
+// RUN: %check_clang_tidy %s bugprone-unintended-adl %t -- \
+// RUN: -config="{CheckOptions: [ \
+// RUN:   {key: bugprone-unintended-adl.AllowedNamespaces, value: 'ignore_me;also::ignore::me'}, \
+// RUN: ]}" --
+
+namespace aspace {
+struct A {};
+void func(const A &);
+} // namespace aspace
+
+namespace bspace {
+void func(int);
+void test() {
+  aspace::A a;
+  func(5);
+  func(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'aspace::func' through ADL [bugprone-unintended-adl]
+  // CHECK-FIXES: {{^}}  aspace::func(a);{{$}}
+}
+} // namespace bspace
+
+namespace ops {
+
+struct Stream {
+} stream;
+Stream <<(Stream , int) {
+  return s;
+}
+Stream <<(Stream , aspace::A) {
+  return s;
+}
+template 
+IStream >>(IStream , int) {
+  return s;
+}
+template 
+IStream >>(IStream , aspace::A) {
+  return s;
+}
+void smooth_operator(Stream);
+
+} // namespace ops
+
+void ops_test() {
+  ops::stream << 5;
+  // no warning
+  operator<<(ops::stream, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  // CHECK-FIXES: {{^}}  ops::operator<<(ops::stream, 5);{{$}}
+  ops::stream << aspace::A();
+  // no warning
+  // CHECK-FIXES: {{^}}  ops::stream << aspace::A();{{$}}
+  operator<<(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  // CHECK-FIXES: {{^}}  ops::operator<<(ops::stream, aspace::A());{{$}}
+
+  ops::stream >> aspace::A();
+  // no warning
+  // CHECK-FIXES: {{^}}  ops::stream >> aspace::A();{{$}}
+  operator>>(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator>>' through ADL [bugprone-unintended-adl]
+  // CHECK-FIXES: {{^}}  ops::operator>>(ops::stream, aspace::A());{{$}}
+
+  smooth_operator(ops::stream);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::smooth_operator' through ADL [bugprone-unintended-adl]
+  // CHECK-FIXES: {{^}}  ops::smooth_operator(ops::stream);{{$}}
+}
+
+namespace std {
+// return types don't matter, returning 'void' everywhere for simplicity
+
+template 
+void swap(T , T );
+template 
+void make_error_code(T);
+template 
+void make_error_condition(T);
+template 
+void data(T);
+template 
+void begin(T);
+template 
+void end(T);
+template 
+void rbegin(T);
+template 
+void rend(T);
+template 
+void crbegin(T);
+template 
+void crend(T);
+template 
+void size(T);
+template 
+void ssize(T);
+template 
+void empty(T);
+
+template 
+void move(T &&);
+template 
+void forward(T &&);
+
+struct byte {};
+
+} // namespace std
+namespace ns {
+
+struct Swappable {};
+
+// whitelisted
+void swap(Swappable , Swappable );
+void make_error_code(Swappable);
+void make_error_condition(Swappable);
+void data(Swappable);
+void begin(Swappable);
+void end(Swappable);
+void rbegin(Swappable);
+void rend(Swappable);
+void crbegin(Swappable);
+void crend(Swappable);
+void size(Swappable);
+void ssize(Swappable);
+void empty(Swappable);
+
+// non-whitelisted
+void move(Swappable);
+void ref(Swappable);
+
+struct Swappable2 {};
+
+} // namespace ns
+struct {
+  template 
+  void operator()(T &&);
+} ref;
+
+void test2() {
+  // TODO add granularity for detecting functions that may always be called unqualified,
+  // versus those that can only be called through the 'using' 'two-step'
+  using namespace std;
+  ns::Swappable a, b;
+  swap(a, b);
+  make_error_code(a);
+  make_error_condition(a);
+  data(a);
+  begin(a);
+  end(a);
+  rbegin(a);
+  rend(a);
+  crbegin(a);
+  crend(a);
+  size(a);
+  ssize(a);
+  empty(a);
+
+  move(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL 

[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-03-13 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 250130.
logan-5 marked 3 inline comments as done.
logan-5 added a comment.

The check now suggests fixes for concrete (i.e. non-template) uses of ADL. 
Re-enabled the check for macros, and eliminated some false positives with 
arrays of dependent size. The check now ignores hidden friends. Added a 
namespace whitelist. Added some tests and ensured that 
"don't-ignore-overloaded-operators" mode works properly in templates.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-generic-lambdas.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-operators.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
@@ -0,0 +1,329 @@
+// RUN: %check_clang_tidy %s bugprone-unintended-adl %t -- \
+// RUN: -config="{CheckOptions: [ \
+// RUN:   {key: bugprone-unintended-adl.AllowedNamespaces, value: 'ignore_me;also::ignore::me'}, \
+// RUN: ]}" --
+
+namespace aspace {
+struct A {};
+void func(const A &);
+} // namespace aspace
+
+namespace bspace {
+void func(int);
+void test() {
+  aspace::A a;
+  func(5);
+  func(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'aspace::func' through ADL [bugprone-unintended-adl]
+  // CHECK-FIXES: {{^}}  aspace::func(a);{{$}}
+}
+} // namespace bspace
+
+namespace ops {
+
+struct Stream {
+} stream;
+Stream <<(Stream , int) {
+  return s;
+}
+Stream <<(Stream , aspace::A) {
+  return s;
+}
+template 
+IStream >>(IStream , int) {
+  return s;
+}
+template 
+IStream >>(IStream , aspace::A) {
+  return s;
+}
+void smooth_operator(Stream);
+
+} // namespace ops
+
+void ops_test() {
+  ops::stream << 5;
+  // no warning
+  operator<<(ops::stream, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  // CHECK-FIXES: {{^}}  ops::operator<<(ops::stream, 5);{{$}}
+  ops::stream << aspace::A();
+  // no warning
+  // CHECK-FIXES: {{^}}  ops::stream << aspace::A();{{$}}
+  operator<<(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  // CHECK-FIXES: {{^}}  ops::operator<<(ops::stream, aspace::A());{{$}}
+
+  ops::stream >> aspace::A();
+  // no warning
+  // CHECK-FIXES: {{^}}  ops::stream >> aspace::A();{{$}}
+  operator>>(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator>>' through ADL [bugprone-unintended-adl]
+  // CHECK-FIXES: {{^}}  ops::operator>>(ops::stream, aspace::A());{{$}}
+
+  smooth_operator(ops::stream);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::smooth_operator' through ADL [bugprone-unintended-adl]
+  // CHECK-FIXES: {{^}}  ops::smooth_operator(ops::stream);{{$}}
+}
+
+namespace std {
+// return types don't matter, returning 'void' everywhere for simplicity
+
+template 
+void swap(T , T );
+template 
+void make_error_code(T);
+template 
+void make_error_condition(T);
+template 
+void data(T);
+template 
+void begin(T);
+template 
+void end(T);
+template 
+void rbegin(T);
+template 
+void rend(T);
+template 
+void crbegin(T);
+template 
+void crend(T);
+template 
+void size(T);
+template 
+void ssize(T);
+template 
+void empty(T);
+
+template 
+void move(T &&);
+template 
+void forward(T &&);
+
+struct byte {};
+
+} // namespace std
+namespace ns {
+
+struct Swappable {};
+
+// whitelisted
+void swap(Swappable , Swappable );
+void make_error_code(Swappable);
+void make_error_condition(Swappable);
+void data(Swappable);
+void begin(Swappable);
+void end(Swappable);
+void rbegin(Swappable);
+void rend(Swappable);
+void crbegin(Swappable);
+void crend(Swappable);
+void size(Swappable);
+void ssize(Swappable);
+void empty(Swappable);
+
+// non-whitelisted
+void move(Swappable);
+void ref(Swappable);
+
+struct Swappable2 {};
+
+} // namespace ns
+struct {
+  template 
+  void operator()(T &&);
+} ref;
+
+void test2() {
+  // TODO add granularity for detecting functions that may always be called unqualified,
+  // versus those that can only be called through the 'using' 'two-step'
+  using namespace std;
+  ns::Swappable a, b;
+  swap(a, b);
+  make_error_code(a);
+  make_error_condition(a);
+  

[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-03-11 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked an inline comment as done.
logan-5 added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp:202
+void macro_test(T t) {
+#define MACRO(x) find_if(x, x, x)
+

Quuxplusone wrote:
> logan-5 wrote:
> > EricWF wrote:
> > > Arguably this is *exactly* the kind of code we want to diagnose.
> > > 
> > > The call in the macro either, 
> > >   * Is a "customization point" and should be whitelisted. Or,
> > >   * It resolves the same in expansion (and can be qualified), Or,
> > >   * It is a bug. 
> > > 
> > > You mentioned false positives in things like `assert`. Can you provide 
> > > examples?
> > Fair enough. Disabling the check for macros does seem short sighted on 
> > closer thought.
> > 
> > When I run the check over LLVM in debug, `assert` expands to 
> > `(__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, 
> > #e) : (void)0)`. If the assert() is inside a function template, the check 
> > claims that `unqualified call to '__assert_rtn' may be resolved through 
> > ADL`. Inspecting the AST, this seems to be due to the fact that `__func__` 
> > has dependent type. I suppose `__func__` could be special cased to be 
> > ignored, or all uglified names, or something?
> Ouch, is that because `__func__` is an array of char with dependent length?
> ```
> template
> void foo() {
> char buf[sizeof(T)];
> memset(buf, '\0', sizeof buf);
> }
> ```
> Unqualified call to `memset`, where one of the arguments has dependent type 
> `char[sizeof(T)]` — does that trigger the diagnostic?
Yep. So, I suppose the check should not trigger for expressions of 
`DependentSizedArrayType` of `char`? Or of any built-in type, really?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282



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


[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-03-11 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked 2 inline comments as done.
logan-5 added a comment.

Thanks for the feedback.

In D72282#1918253 , @EricWF wrote:

> - This check should suggest fixes. It knows what function is actually being 
> resolved, and it has enough information to create a minimally qualified name 
> that resolves it.


True, though of course it will only be able to do so for the non-template 
version of the warning, since in the template version it only knows that the 
call _may_ be resolved through ADL.

> - This check should ignore hidden friends, since their entire purpose is to 
> be called via ADL.
> - This check should allow whitelisting namespaces that opt-out of ADL into 
> their namespace. This makes it much easier to roll out the clang-tidy 
> incrementally.

I want to make absolutely sure I understand the last bullet. You'd like a 
whitelist of namespaces where, if a call is resolved by ADL to a function 
within any of those namespaces, the check doesn't fire?

I like all these suggestions. I'll work on an updated patch.




Comment at: clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.h:27
+class UnintendedADLCheck : public ClangTidyCheck {
+  const bool IgnoreOverloadedOperators;
+  const std::vector AllowedIdentifiers;

Quuxplusone wrote:
> EricWF wrote:
> > I think we should always ignore operators. I don't see value in having a 
> > mode where every comparison triggers this warning.
> > 
> I think there's value in that mode, for library writers (not libc++) who 
> really care about finding every unintentional ADL in their whole library. The 
> standard library is designed not-to-work with types like 
> [`Holder`](https://quuxplusone.github.io/blog/2019/09/26/uglification-doesnt-stop-adl/),
>  but someone else's library might be designed to work even in that case, and 
> then they'd want to hear about ADL lookups for things like `operator,`. 
> Besides, it's just 1 extra line of code in the patch, isn't it?
> 
> However, I now think I may not understand how this check works. I thought it 
> looked for unqualified calls (even in templates) that "may" use ADL, but now 
> that I look again at the tests, it seems to trigger only on concrete calls 
> (in concrete template instantiations) that "do" use ADL, which sounds still 
> useful but much less comprehensive than I had thought.
> 
> I think it would catch
> ```
> template void foo(T t) { t, 0; }
> struct S { friend void operator,(S, int); };
> template void foo(S);
> ```
> but not
> ```
> template void foo(T t) { t, 0; }
> struct S { friend void operator,(S, int); };
> template void foo(int);
> ```
> or
> ```
> template void foo(T t) { t, 0; }
> ```
> is that right?
@Quuxplusone your initial understanding was right; the check fires on both 
templates that "may" use ADL as well as concrete instantiations that "do." 
There are tests for both, but I see now that I failed to add tests for the 
"may" case for operators, which I'll do.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp:202
+void macro_test(T t) {
+#define MACRO(x) find_if(x, x, x)
+

EricWF wrote:
> Arguably this is *exactly* the kind of code we want to diagnose.
> 
> The call in the macro either, 
>   * Is a "customization point" and should be whitelisted. Or,
>   * It resolves the same in expansion (and can be qualified), Or,
>   * It is a bug. 
> 
> You mentioned false positives in things like `assert`. Can you provide 
> examples?
Fair enough. Disabling the check for macros does seem short sighted on closer 
thought.

When I run the check over LLVM in debug, `assert` expands to 
`(__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : 
(void)0)`. If the assert() is inside a function template, the check claims that 
`unqualified call to '__assert_rtn' may be resolved through ADL`. Inspecting 
the AST, this seems to be due to the fact that `__func__` has dependent type. I 
suppose `__func__` could be special cased to be ignored, or all uglified names, 
or something?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282



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


[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-03-11 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Just giving this a friendly ping!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282



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


[PATCH] D74238: [clang] Improve diagnostic note for implicit conversion sequences that would work if more than one implicit user-defined conversion were allowed.

2020-03-04 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Pinging this and the patches it depends on. I figured it would need a rebase by 
now, but it still applies cleanly to trunk.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74238/new/

https://reviews.llvm.org/D74238



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


[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-02-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 243307.
logan-5 marked an inline comment as done.
logan-5 added a comment.

Changed `Whitelist` to `AllowedIdentifiers`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-generic-lambdas.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-operators.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
@@ -0,0 +1,213 @@
+// RUN: %check_clang_tidy %s bugprone-unintended-adl %t
+
+namespace aspace {
+struct A {};
+void func(const A &);
+} // namespace aspace
+
+namespace bspace {
+void func(int);
+void test() {
+  aspace::A a;
+  func(5);
+  func(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'aspace::func' through ADL [bugprone-unintended-adl]
+}
+} // namespace bspace
+
+namespace ops {
+
+struct Stream {
+} stream;
+Stream <<(Stream , int) {
+  return s;
+}
+Stream <<(Stream , aspace::A) {
+  return s;
+}
+template 
+IStream >>(IStream , int) {
+  return s;
+}
+template 
+IStream >>(IStream , aspace::A) {
+  return s;
+}
+void smooth_operator(Stream);
+
+} // namespace ops
+
+void ops_test() {
+  ops::stream << 5;
+  // no warning
+  operator<<(ops::stream, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  ops::stream << aspace::A();
+  // no warning
+  operator<<(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+
+  ops::stream >> aspace::A();
+  // no warning
+  operator>>(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator>>' through ADL [bugprone-unintended-adl]
+
+  smooth_operator(ops::stream);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::smooth_operator' through ADL [bugprone-unintended-adl]
+}
+
+namespace std {
+// return types don't matter, returning 'void' everywhere for simplicity
+
+template 
+void swap(T , T );
+template 
+void make_error_code(T);
+template 
+void make_error_condition(T);
+template 
+void data(T);
+template 
+void begin(T);
+template 
+void end(T);
+template 
+void rbegin(T);
+template 
+void rend(T);
+template 
+void crbegin(T);
+template 
+void crend(T);
+template 
+void size(T);
+template 
+void ssize(T);
+template 
+void empty(T);
+
+template 
+void move(T &&);
+template 
+void forward(T &&);
+
+struct byte {};
+
+} // namespace std
+namespace ns {
+
+struct Swappable {};
+
+// whitelisted
+void swap(Swappable , Swappable );
+void make_error_code(Swappable);
+void make_error_condition(Swappable);
+void data(Swappable);
+void begin(Swappable);
+void end(Swappable);
+void rbegin(Swappable);
+void rend(Swappable);
+void crbegin(Swappable);
+void crend(Swappable);
+void size(Swappable);
+void ssize(Swappable);
+void empty(Swappable);
+
+// non-whitelisted
+void move(Swappable);
+void ref(Swappable);
+
+struct Swappable2 {};
+
+} // namespace ns
+struct {
+  template 
+  void operator()(T &&);
+} ref;
+
+void test2() {
+  // TODO add granularity for detecting functions that may always be called unqualified,
+  // versus those that can only be called through the 'using' 'two-step'
+  using namespace std;
+  ns::Swappable a, b;
+  swap(a, b);
+  make_error_code(a);
+  make_error_condition(a);
+  data(a);
+  begin(a);
+  end(a);
+  rbegin(a);
+  rend(a);
+  crbegin(a);
+  crend(a);
+  size(a);
+  ssize(a);
+  empty(a);
+
+  move(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+}
+
+template 
+void foo(T t) {
+  using namespace std;
+  swap(t, t);
+  make_error_code(t);
+  make_error_condition(t);
+  data(t);
+  begin(t);
+  end(t);
+  rbegin(t);
+  rend(t);
+  crbegin(t);
+  crend(t);
+  size(t);
+  ssize(t);
+  empty(t);
+
+  move(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+  // CHECK-MESSAGES: [[@LINE-2]]:3: note: with argument type 'struct ns::Swappable'
+  // CHECK-MESSAGES: [[@LINE-3]]:3: warning: unqualified call to 'move' may be resolved through ADL [bugprone-unintended-adl]
+
+  std::swap(t, t);
+  std::move(t);
+
+  ref(t); // function 

[PATCH] D74238: [clang] [clang] Improve diagnostic note for implicit conversion sequences that would work if more than one implicit user-defined conversion were allowed.

2020-02-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added a reviewer: rsmith.
logan-5 added a project: clang.
Herald added a subscriber: cfe-commits.

The current text of the 'note' diagnostic for bad conversions is confusing in 
the presence of user-defined conversion operations: https://godbolt.org/z/zrgeHH
For the first error, the conversion function is simply pointed at in a note 
without any further explanation. For the second error, the final note claims 
there is no conversion from X2 to Y2, even though it is plainly visible in the 
source code. The reason for the error is that only one implicit user-defined 
conversion may be applied in these circumstances, but the error message is 
misleading to those who may not know this rule.

This is determined by searching for these illegal conversions in 
CompleteNonViableCandidate after overload resolution fails.

Depends on D74234 . Also depends on D74235 
.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74238

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Overload.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CXX/drs/dr0xx.cpp
  clang/test/SemaCXX/address-space-ctor.cpp
  clang/test/SemaCXX/constructor-initializer.cpp
  clang/test/SemaCXX/user-defined-conversions.cpp

Index: clang/test/SemaCXX/user-defined-conversions.cpp
===
--- clang/test/SemaCXX/user-defined-conversions.cpp
+++ clang/test/SemaCXX/user-defined-conversions.cpp
@@ -97,3 +97,51 @@
 a = b; // expected-error{{calling a private constructor of class 'rdar10202900::A'}}
   }
 }
+
+namespace more_than_one {
+
+namespace std_example {
+struct X {
+  operator int();
+};
+
+struct Y {
+  operator X(); // expected-note{{converting from 'more_than_one::std_example::Y' to 'more_than_one::std_example::X' would apply more than one implicit user-defined conversion}}
+};
+
+Y a;
+int b = a; // expected-error{{no viable conversion}}
+int c = X(a);
+}
+
+namespace ctors {
+struct X {};
+struct Y {
+  Y(X);
+};
+struct Z { // expected-note 2{{candidate constructor (the implicit}}
+  Z(Y);   // expected-note{{converting from 'more_than_one::ctors::X' to 'more_than_one::ctors::Y' would apply more than one implicit user-defined conversion}}
+};
+
+X x;
+Z z = x; // expected-error{{no viable conversion}}
+Z z2 = Y(x);
+}
+
+namespace ops {
+
+struct Y;
+struct X {
+  operator Y() const; // expected-note {{converting from 'more_than_one::ops::X' to 'more_than_one::ops::Y' would apply more than one implicit user-defined conversion}}
+};
+struct Y {};
+struct Z { // expected-note 2{{candidate constructor (the implicit}}
+  Z(Y);   // expected-note{{converting from 'more_than_one::ops::X' to 'more_than_one::ops::Y' would apply more than one implicit user-defined conversion}}
+};
+
+X x;
+Z z = x; // expected-error{{no viable conversion}}
+Z z2 = static_cast(x);
+}
+} // namespace more_than_one
+
Index: clang/test/SemaCXX/constructor-initializer.cpp
===
--- clang/test/SemaCXX/constructor-initializer.cpp
+++ clang/test/SemaCXX/constructor-initializer.cpp
@@ -306,7 +306,7 @@
 namespace PR10758 {
 struct A;
 struct B {
-  B (A const &); // expected-note 2 {{candidate constructor not viable: no known conversion from 'const PR10758::B' to 'const PR10758::A &' for 1st argument}}
+  B (A const &); // expected-note 2 {{candidate constructor not viable: converting from 'const PR10758::B' to 'const PR10758::A &' would apply more than one implicit user-defined conversion}}
   B (B &); // expected-note 2 {{candidate constructor not viable: 1st argument ('const PR10758::B') would lose const qualifier}}
 };
 struct A {
Index: clang/test/SemaCXX/address-space-ctor.cpp
===
--- clang/test/SemaCXX/address-space-ctor.cpp
+++ clang/test/SemaCXX/address-space-ctor.cpp
@@ -6,8 +6,8 @@
   int i;
 };
 
-//expected-note@-5{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const MyType &' for 1st argument}}
-//expected-note@-6{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'MyType &&' for 1st argument}}
+//expected-note@-5{{candidate constructor (the implicit copy constructor) not viable: converting from 'int' to 'const MyType &' would apply more than one implicit user-defined conversion}}
+//expected-note@-6{{candidate constructor (the implicit move constructor) not viable: converting from 'int' to 'MyType &&' would apply more than one implicit user-defined conversion}}
 //expected-note@-6{{candidate constructor ignored: cannot be used to construct an object in address space '__attribute__((address_space(10)))'}}
 //expected-note@-8{{candidate constructor ignored: cannot be used to construct an 

[PATCH] D74009: [clang] Improve diagnostic note for implicit conversions that are disallowed because they involve more than one user-defined conversion.

2020-02-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 abandoned this revision.
logan-5 added a comment.

I split this patch into multiple, and reworked the implementation. The new 
stuff lives here and here and here: D74238  
D74234  D74235 



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74009/new/

https://reviews.llvm.org/D74009



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


[PATCH] D74235: [clang] [NFC] Rename Sema::DiagnoseMultipleUserConversion to DiagnoseAmbiguousUserConversion

2020-02-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added a reviewer: rsmith.
logan-5 added a project: clang.
Herald added a subscriber: cfe-commits.
logan-5 added a child revision: D74238: [clang] [clang] Improve diagnostic note 
for implicit conversion sequences that would work if more than one implicit 
user-defined conversion were allowed..

This is to avoid confusion in an upcoming patch that uses the term "multiple 
user-defined conversions" to refer to (invalid) implicit conversion sequences 
that involve applying more than one user conversion.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74235

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp


Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -3606,7 +3606,7 @@
 }
 
 bool
-Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
+Sema::DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType) {
   ImplicitConversionSequence ICS;
   OverloadCandidateSet CandidateSet(From->getExprLoc(),
 OverloadCandidateSet::CSK_Normal);
@@ -5465,7 +5465,7 @@
   if (!ICS.isBad())
 return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
 
-  if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy))
+  if (!DiagnoseAmbiguousUserDefinedConversion(From, Context.BoolTy))
 return Diag(From->getBeginLoc(), diag::err_typecheck_bool_condition)
<< From->getType() << From->getSourceRange();
   return ExprError();
@@ -5579,7 +5579,7 @@
 break;
   case ImplicitConversionSequence::AmbiguousConversion:
   case ImplicitConversionSequence::BadConversion:
-if (!S.DiagnoseMultipleUserDefinedConversion(From, T))
+if (!S.DiagnoseAmbiguousUserDefinedConversion(From, T))
   return S.Diag(From->getBeginLoc(),
 diag::err_typecheck_converted_constant_expression)
  << From->getType() << From->getSourceRange() << T;
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -3011,7 +3011,7 @@
  bool CStyle, bool );
   bool IsFunctionConversion(QualType FromType, QualType ToType,
 QualType );
-  bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
+  bool DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType);
   bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg);
 
   ExprResult PerformMoveOrCopyInitialization(const InitializedEntity ,


Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -3606,7 +3606,7 @@
 }
 
 bool
-Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
+Sema::DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType) {
   ImplicitConversionSequence ICS;
   OverloadCandidateSet CandidateSet(From->getExprLoc(),
 OverloadCandidateSet::CSK_Normal);
@@ -5465,7 +5465,7 @@
   if (!ICS.isBad())
 return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
 
-  if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy))
+  if (!DiagnoseAmbiguousUserDefinedConversion(From, Context.BoolTy))
 return Diag(From->getBeginLoc(), diag::err_typecheck_bool_condition)
<< From->getType() << From->getSourceRange();
   return ExprError();
@@ -5579,7 +5579,7 @@
 break;
   case ImplicitConversionSequence::AmbiguousConversion:
   case ImplicitConversionSequence::BadConversion:
-if (!S.DiagnoseMultipleUserDefinedConversion(From, T))
+if (!S.DiagnoseAmbiguousUserDefinedConversion(From, T))
   return S.Diag(From->getBeginLoc(),
 diag::err_typecheck_converted_constant_expression)
  << From->getType() << From->getSourceRange() << T;
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -3011,7 +3011,7 @@
  bool CStyle, bool );
   bool IsFunctionConversion(QualType FromType, QualType ToType,
 QualType );
-  bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
+  bool DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType);
   bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg);
 
   ExprResult PerformMoveOrCopyInitialization(const InitializedEntity ,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74234: [clang] [NFC] Change boolean SuppressUserConversions parameters to an enum

2020-02-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added a reviewer: rsmith.
logan-5 added a project: clang.
Herald added a subscriber: cfe-commits.
logan-5 added a child revision: D74238: [clang] [clang] Improve diagnostic note 
for implicit conversion sequences that would work if more than one implicit 
user-defined conversion were allowed..

This is groundwork for a subsequent patch that adds a third mode for searching 
for user conversions.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74234

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaCodeComplete.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLookup.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaOverload.cpp

Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -1317,7 +1317,7 @@
 /// is not an option. See TryImplicitConversion for more information.
 static ImplicitConversionSequence
 TryUserDefinedConversion(Sema , Expr *From, QualType ToType,
- bool SuppressUserConversions,
+ Sema::UserDefinedConversions UserConversions,
  AllowedExplicit AllowExplicit,
  bool InOverloadResolution,
  bool CStyle,
@@ -1325,7 +1325,7 @@
  bool AllowObjCConversionOnExplicit) {
   ImplicitConversionSequence ICS;
 
-  if (SuppressUserConversions) {
+  if (UserConversions == Sema::UserDefinedConversions::Suppress) {
 // We're not in the case above, so there is no conversion that
 // we can perform.
 ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
@@ -1410,8 +1410,8 @@
 /// but will instead return an implicit conversion sequence of kind
 /// "BadConversion".
 ///
-/// If @p SuppressUserConversions, then user-defined conversions are
-/// not permitted.
+/// If @p UserConversions is UserDefinedConversions::Suppress, then 
+/// user-defined conversions are not permitted.
 /// If @p AllowExplicit, then explicit user-defined conversions are
 /// permitted.
 ///
@@ -1420,7 +1420,7 @@
 /// be initialized with __strong id* or __weak id* arguments.
 static ImplicitConversionSequence
 TryImplicitConversion(Sema , Expr *From, QualType ToType,
-  bool SuppressUserConversions,
+  Sema::UserDefinedConversions UserConversions,
   AllowedExplicit AllowExplicit,
   bool InOverloadResolution,
   bool CStyle,
@@ -1467,7 +1467,7 @@
 return ICS;
   }
 
-  return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions,
+  return TryUserDefinedConversion(S, From, ToType, UserConversions,
   AllowExplicit, InOverloadResolution, CStyle,
   AllowObjCWritebackConversion,
   AllowObjCConversionOnExplicit);
@@ -1475,12 +1475,12 @@
 
 ImplicitConversionSequence
 Sema::TryImplicitConversion(Expr *From, QualType ToType,
-bool SuppressUserConversions,
+Sema::UserDefinedConversions UserConversions,
 AllowedExplicit AllowExplicit,
 bool InOverloadResolution,
 bool CStyle,
 bool AllowObjCWritebackConversion) {
-  return ::TryImplicitConversion(*this, From, ToType, SuppressUserConversions,
+  return ::TryImplicitConversion(*this, From, ToType, UserConversions,
  AllowExplicit, InOverloadResolution, CStyle,
  AllowObjCWritebackConversion,
  /*AllowObjCConversionOnExplicit=*/false);
@@ -1513,7 +1513,7 @@
 CheckObjCBridgeRelatedConversions(From->getBeginLoc(), ToType,
   From->getType(), From);
   ICS = ::TryImplicitConversion(*this, From, ToType,
-/*SuppressUserConversions=*/false,
+UserDefinedConversions::Allow,
 AllowExplicit ? AllowedExplicit::All
   : AllowedExplicit::None,
 /*InOverloadResolution=*/false,
@@ -3334,17 +3334,19 @@
 if (Usable) {
   // If the first argument is (a reference to) the target type,
   // suppress conversions.
-  bool SuppressUserConversions = isFirstArgumentCompatibleWithType(
-  S.Context, Info.Constructor, ToType);
+  Sema::UserDefinedConversions UserConversions = 
+ isFirstArgumentCompatibleWithType(S.Context, Info.Constructor, ToType)
+? Sema::UserDefinedConversions::Suppress
+: Sema::UserDefinedConversions::Allow;
   if 

[PATCH] D74009: [clang] Improve diagnostic note for implicit conversions that are disallowed because they involve more than one user-defined conversion.

2020-02-05 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

In D74009#1858353 , @rsmith wrote:

> Have you looked into whether you can defer the check for conversion via 
> multiple user-defined conversions until we come to call 
> `CompleteNonViableCandidate` after finding no viable functions?


That's a good idea, and does seem more efficient than checking for multiple 
conversions every time. I'll look into that, and also split this patch into two 
as @jkorous suggested.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74009/new/

https://reviews.llvm.org/D74009



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


[PATCH] D74009: [clang] Improve diagnostic note for implicit conversions that are disallowed because they involve more than one user-defined conversion.

2020-02-04 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added a reviewer: rsmith.
logan-5 added a project: clang.
Herald added a subscriber: cfe-commits.

The current text of the 'note' diagnostic for bad conversions is confusing in 
the presence of user-defined conversion operations: https://godbolt.org/z/zrgeHH
For the first error, the conversion function is simply pointed at in a note 
without any further explanation. For the second error, the final note claims 
there is no conversion from X2 to Y2, even though it is plainly visible in the 
source code. The reason for the error is that only one implicit user-defined 
conversion may be applied in these circumstances, but the error message is 
misleading to those who may not know this rule.

This patch clarifies this situation with a better diagnostic message. It does 
so by finding user conversions even where they are not allowed, and then 
discarding them afterward as invalid, but keeping a record that they existed. 
There is also a stronger mode (`UDC_Skip`) for skipping the search for 
user-defined conversions outright, which matches the old behavior and is 
retained to prevent infinite recursions.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74009

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Overload.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaCodeComplete.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLookup.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CXX/drs/dr0xx.cpp
  clang/test/SemaCXX/user-defined-conversions.cpp

Index: clang/test/SemaCXX/user-defined-conversions.cpp
===
--- clang/test/SemaCXX/user-defined-conversions.cpp
+++ clang/test/SemaCXX/user-defined-conversions.cpp
@@ -97,3 +97,31 @@
 a = b; // expected-error{{calling a private constructor of class 'rdar10202900::A'}}
   }
 }
+
+namespace more_than_one {
+  struct X {
+operator int();
+  };
+
+  struct Y {
+operator X(); // expected-note{{converting from 'more_than_one::X' to 'int' applies more than one implicit user-defined conversion}}
+  };
+
+  Y a;
+  int b = a; // expected-error{{no viable conversion}}
+  int c = X(a);
+
+  struct X2 {};
+
+  struct Y2 {
+Y2(X2);
+  };
+
+  struct Z { // expected-note 2{{candidate constructor (the implicit}}
+Z(Y2); // expected-note{{converting from 'more_than_one::X2' to 'more_than_one::Y2' applies more than one implicit user-defined conversion}}
+  };
+
+  X2 x;
+  Z z = x; // expected-error{{no viable conversion}}
+  Z z2 = Y2(x);
+}
Index: clang/test/CXX/drs/dr0xx.cpp
===
--- clang/test/CXX/drs/dr0xx.cpp
+++ clang/test/CXX/drs/dr0xx.cpp
@@ -964,7 +964,7 @@
   struct C {};
   struct B {
 B(B&); // expected-note 0-1{{candidate}}
-B(C); // expected-note 0-1{{no known conversion from 'dr84::B' to 'dr84::C'}}
+B(C); // expected-note 0-1{{'dr84::B' to 'dr84::C' applies more than one implicit user-defined conversion}}
 operator C() const;
   };
   A a;
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -93,6 +93,7 @@
 IsUserDefinedConversion(Sema , Expr *From, QualType ToType,
 UserDefinedConversionSequence& User,
 OverloadCandidateSet& Conversions,
+Sema::UserDefinedConversionsKind UserConversions,
 AllowedExplicit AllowExplicit,
 bool AllowObjCConversionOnExplicit);
 
@@ -1317,17 +1318,15 @@
 /// is not an option. See TryImplicitConversion for more information.
 static ImplicitConversionSequence
 TryUserDefinedConversion(Sema , Expr *From, QualType ToType,
- bool SuppressUserConversions,
+ Sema::UserDefinedConversionsKind UserConversions,
  AllowedExplicit AllowExplicit,
  bool InOverloadResolution,
  bool CStyle,
  bool AllowObjCWritebackConversion,
  bool AllowObjCConversionOnExplicit) {
   ImplicitConversionSequence ICS;
-
-  if (SuppressUserConversions) {
-// We're not in the case above, so there is no conversion that
-// we can perform.
+  
+  if (UserConversions == Sema::UDC_Skip) {
 ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
 return ICS;
   }
@@ -1336,7 +1335,7 @@
   OverloadCandidateSet Conversions(From->getExprLoc(),
OverloadCandidateSet::CSK_Normal);
   switch (IsUserDefinedConversion(S, From, ToType, ICS.UserDefined,
-  Conversions, AllowExplicit,
+  Conversions, 

[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-27 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 240691.
logan-5 added a comment.

Rebased with trunk. Updated whitelist to include more standard designated 
customization points .


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-generic-lambdas.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-operators.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
@@ -0,0 +1,213 @@
+// RUN: %check_clang_tidy %s bugprone-unintended-adl %t
+
+namespace aspace {
+struct A {};
+void func(const A &);
+} // namespace aspace
+
+namespace bspace {
+void func(int);
+void test() {
+  aspace::A a;
+  func(5);
+  func(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'aspace::func' through ADL [bugprone-unintended-adl]
+}
+} // namespace bspace
+
+namespace ops {
+
+struct Stream {
+} stream;
+Stream <<(Stream , int) {
+  return s;
+}
+Stream <<(Stream , aspace::A) {
+  return s;
+}
+template 
+IStream >>(IStream , int) {
+  return s;
+}
+template 
+IStream >>(IStream , aspace::A) {
+  return s;
+}
+void smooth_operator(Stream);
+
+} // namespace ops
+
+void ops_test() {
+  ops::stream << 5;
+  // no warning
+  operator<<(ops::stream, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  ops::stream << aspace::A();
+  // no warning
+  operator<<(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+
+  ops::stream >> aspace::A();
+  // no warning
+  operator>>(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator>>' through ADL [bugprone-unintended-adl]
+
+  smooth_operator(ops::stream);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::smooth_operator' through ADL [bugprone-unintended-adl]
+}
+
+namespace std {
+// return types don't matter, returning 'void' everywhere for simplicity
+
+template 
+void swap(T , T );
+template 
+void make_error_code(T);
+template 
+void make_error_condition(T);
+template 
+void data(T);
+template 
+void begin(T);
+template 
+void end(T);
+template 
+void rbegin(T);
+template 
+void rend(T);
+template 
+void crbegin(T);
+template 
+void crend(T);
+template 
+void size(T);
+template 
+void ssize(T);
+template 
+void empty(T);
+
+template 
+void move(T &&);
+template 
+void forward(T &&);
+
+struct byte {};
+
+} // namespace std
+namespace ns {
+
+struct Swappable {};
+
+// whitelisted
+void swap(Swappable , Swappable );
+void make_error_code(Swappable);
+void make_error_condition(Swappable);
+void data(Swappable);
+void begin(Swappable);
+void end(Swappable);
+void rbegin(Swappable);
+void rend(Swappable);
+void crbegin(Swappable);
+void crend(Swappable);
+void size(Swappable);
+void ssize(Swappable);
+void empty(Swappable);
+
+// non-whitelisted
+void move(Swappable);
+void ref(Swappable);
+
+struct Swappable2 {};
+
+} // namespace ns
+struct {
+  template 
+  void operator()(T &&);
+} ref;
+
+void test2() {
+  // TODO add granularity for detecting functions that may always be called unqualified,
+  // versus those that can only be called through the 'using' 'two-step'
+  using namespace std;
+  ns::Swappable a, b;
+  swap(a, b);
+  make_error_code(a);
+  make_error_condition(a);
+  data(a);
+  begin(a);
+  end(a);
+  rbegin(a);
+  rend(a);
+  crbegin(a);
+  crend(a);
+  size(a);
+  ssize(a);
+  empty(a);
+
+  move(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+}
+
+template 
+void foo(T t) {
+  using namespace std;
+  swap(t, t);
+  make_error_code(t);
+  make_error_condition(t);
+  data(t);
+  begin(t);
+  end(t);
+  rbegin(t);
+  rend(t);
+  crbegin(t);
+  crend(t);
+  size(t);
+  ssize(t);
+  empty(t);
+
+  move(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+  // CHECK-MESSAGES: [[@LINE-2]]:3: note: with argument type 'struct ns::Swappable'
+  // CHECK-MESSAGES: [[@LINE-3]]:3: warning: unqualified call to 'move' may be resolved through ADL [bugprone-unintended-adl]
+
+  

[PATCH] D72378: [clang-tidy] Add `bugprone-reserved-identifier`

2020-01-16 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 238640.
logan-5 added a comment.

Should be good now.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72378/new/

https://reviews.llvm.org/D72378

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h
  clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-reserved-identifier.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-dcl37-c.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-dcl51-cpp.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/system/system-header.h
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/user-header.h
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-c.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-invert.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -0,0 +1,206 @@
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- -- \
+// RUN:   -I%S/Inputs/bugprone-reserved-identifier \
+// RUN:   -isystem %S/Inputs/bugprone-reserved-identifier/system
+
+// no warnings expected without -header-filter=
+#include "user-header.h"
+#include 
+
+#define _MACRO(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses identifier '_MACRO', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define MACRO(m) int m = 0{{$}}
+
+namespace _Ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses identifier '_Ns', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace Ns {{{$}}
+
+class _Object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '_Object', which is a reserved identifier [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class Object {{{$}}
+  int _Member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '_Member', which is a reserved identifier [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int Member;{{$}}
+};
+
+float _Global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '_Global', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float Global;{{$}}
+
+void _Function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses identifier '_Function', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void Function() {}{{$}}
+
+using _Alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '_Alias', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using Alias = int;{{$}}
+
+template 
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: declaration uses identifier '_TemplateParam', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}template {{$}}
+struct S {};
+
+} // namespace _Ns
+
+//
+
+#define __macro(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses identifier '__macro', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define macro(m) int m = 0{{$}}
+
+namespace __ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses identifier '__ns', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace ns {{{$}}
+class __object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '__object', which is a reserved identifier [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class _object {{{$}}
+  int __member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '__member', which is a reserved identifier [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int _member;{{$}}
+};
+
+float __global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '__global', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float _global;{{$}}
+
+void __function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses identifier '__function', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void _function() {}{{$}}
+
+using __alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '__alias', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using 

[PATCH] D72378: [clang-tidy] Add `bugprone-reserved-identifier`

2020-01-16 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Great! In that case, I'll need help committing this, as well as the thing it 
depends on, https://reviews.llvm.org/D72284 (which has also been LGTM'd).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72378/new/

https://reviews.llvm.org/D72378



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


[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-15 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 238328.
logan-5 added a comment.

Added TODO comment.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-generic-lambdas.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-operators.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
@@ -0,0 +1,162 @@
+// RUN: %check_clang_tidy %s bugprone-unintended-adl %t
+
+namespace aspace {
+struct A {};
+void func(const A &);
+} // namespace aspace
+
+namespace bspace {
+void func(int);
+void test() {
+  aspace::A a;
+  func(5);
+  func(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'aspace::func' through ADL [bugprone-unintended-adl]
+}
+} // namespace bspace
+
+namespace ops {
+
+struct Stream {
+} stream;
+Stream <<(Stream , int) {
+  return s;
+}
+Stream <<(Stream , aspace::A) {
+  return s;
+}
+template 
+IStream >>(IStream , int) {
+  return s;
+}
+template 
+IStream >>(IStream , aspace::A) {
+  return s;
+}
+void smooth_operator(Stream);
+
+} // namespace ops
+
+void ops_test() {
+  ops::stream << 5;
+  // no warning
+  operator<<(ops::stream, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  ops::stream << aspace::A();
+  // no warning
+  operator<<(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+
+  ops::stream >> aspace::A();
+  // no warning
+  operator>>(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator>>' through ADL [bugprone-unintended-adl]
+
+  smooth_operator(ops::stream);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::smooth_operator' through ADL [bugprone-unintended-adl]
+}
+
+namespace std {
+// return types don't matter, returning 'void' everywhere for simplicity
+
+template 
+void swap(T , T );
+template 
+void make_error_code(T);
+template 
+void make_error_condition(T);
+
+template 
+void move(T &&);
+template 
+void forward(T &&);
+
+struct byte {};
+
+} // namespace std
+namespace ns {
+
+struct Swappable {};
+
+// whitelisted
+void swap(Swappable , Swappable );
+void make_error_code(Swappable);
+void make_error_condition(Swappable);
+
+// non-whitelisted
+void move(Swappable);
+void ref(Swappable);
+
+struct Swappable2 {};
+
+} // namespace ns
+struct {
+  template 
+  void operator()(T &&);
+} ref;
+
+void test2() {
+  // TODO add granularity for detecting functions that may always be called unqualified,
+  // versus those that can only be called through the 'using' 'two-step'
+  using namespace std;
+  ns::Swappable a, b;
+  swap(a, b);
+  make_error_code(a);
+  make_error_condition(a);
+  move(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+}
+
+template 
+void foo(T t) {
+  using namespace std;
+  swap(t, t);
+  make_error_code(t);
+  make_error_condition(t);
+
+  move(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+  // CHECK-MESSAGES: [[@LINE-2]]:3: note: with argument type 'struct ns::Swappable'
+  // CHECK-MESSAGES: [[@LINE-3]]:3: warning: unqualified call to 'move' may be resolved through ADL [bugprone-unintended-adl]
+
+  std::swap(t, t);
+  std::move(t);
+
+  ref(t); // function objects bypass ADL, this always calls ::ref
+  ::ref(t);
+}
+
+template 
+void operator<<(T &&, U &&);
+
+template 
+void bar(T t) {
+  t << 5;
+  operator<<(t, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  // CHECK-MESSAGES: [[@LINE-2]]:3: note: with argument types 'struct ops::Stream', 'int'
+  // CHECK-MESSAGES: [[@LINE-3]]:3: warning: unqualified call to 'operator<<' may be resolved through ADL [bugprone-unintended-adl]
+}
+
+void instantiator() {
+  foo(ns::Swappable()); // instantiation will use ADL
+  foo(5);   // instantiation will not use ADL
+
+  bar(ops::Stream()); // instantiation will use ADL
+  bar(aspace::A());   // instantiation will not use ADL
+}
+
+template 
+void macro_test(T t) {
+#define MACRO(x) find_if(x, x, x)

[PATCH] D72284: [clang-tidy] Factor out renaming logic from readability-identifier-naming

2020-01-15 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked 2 inline comments as done.
logan-5 added inline comments.



Comment at: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h:29
+public:
+  RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
+  ~RenamerClangTidyCheck();

logan-5 wrote:
> njames93 wrote:
> > Should this be protected as this class should never be instantiated 
> > directly. Also the definition could be moved inline as its just a 
> > delegating constructor
> The constructor (and destructor) can't be inline, since they need to be able 
> to see the specialization of `DenseMapInfo` in the cpp.
> 
> I could change it to `protected` to clean up the interface -- though it won't 
> strictly change anything, since the class already has pure virtual functions 
> so it's not instantiable.
Searched the LLVM codebase for other abstract base classes with explicitly 
defined constructors (e.g. `MakeSmartPtrCheck` in clang-tidy), and their 
constructors seem to be public. I think I'll keep this one public too for 
consistency.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72284/new/

https://reviews.llvm.org/D72284



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


[PATCH] D72378: [clang-tidy] Add `bugprone-reserved-identifier`

2020-01-14 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp:27-34
+static const char NonReservedMessage[] =
+"declaration uses identifier '%0', which is not a reserved "
+"identifier";
+static const char GlobalUnderscoreMessage[] =
+"declaration uses identifier '%0', which is reserved in the global "
+"namespace; this causes undefined behavior";
+static const char DefaultMessage[] = "declaration uses reserved identifier "

aaron.ballman wrote:
> I think you can reasonably combine these into a single diagnostic using 
> `%select`. e.g.,
> `"declaration uses identifier %0, which is %select{a reserved identifier|not 
> a reserved identifier|reserved in the global namespace}1"`
> 
> I took out the bits about causing undefined behavior because that doesn't 
> really add much to the diagnostic (the "is a reserved identifier" bit should 
> be sufficient). Also, I removed the manual quoting around the `%0` because it 
> shouldn't be needed if you pass in a `NamedDecl*` as opposed to a string 
> (which you should prefer doing because it automatically formats the 
> identifier properly).
I don't have access to a `NamedDecl*` for a couple reasons, one being that the 
same diagnostic is used for both declarations and macro definitions. The 
%select change sounds like a good one--I'll do that (or I already did it, 
depending when this comment shows up).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72378/new/

https://reviews.llvm.org/D72378



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


[PATCH] D72378: [clang-tidy] Add `bugprone-reserved-identifier`

2020-01-14 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 238064.
logan-5 marked 6 inline comments as done.
logan-5 added a comment.

Renamed check option from "Whitelist" to "AllowedIdentifiers". Added note about 
missing checks in documentation. Changed to use a %select for diagnostic text. 
Some nits.

The check does due diligence when run over LLVM (after whitelisting a couple 
things), correctly flagging a few suspicious names scattered about.

The inverted mode is a bit cumbersome at the moment to use on libc++ (since 
libc++ legitimately defines lots of non-reserved names (that's its job)). One 
could whitelist every name the standard defines, but I'd like to add some logic 
in a future patch that is smarter about which names need to be reserved in 
inverted mode -- something like, flagging private class members but not public 
ones, for example.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72378/new/

https://reviews.llvm.org/D72378

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h
  clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-reserved-identifier.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-dcl37-c.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-dcl51-cpp.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/system/system-header.h
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/user-header.h
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-c.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-invert.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -0,0 +1,206 @@
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- -- \
+// RUN:   -I%S/Inputs/bugprone-reserved-identifier \
+// RUN:   -isystem %S/Inputs/bugprone-reserved-identifier/system
+
+// no warnings expected without -header-filter=
+#include "user-header.h"
+#include 
+
+#define _MACRO(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses identifier '_MACRO', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define MACRO(m) int m = 0{{$}}
+
+namespace _Ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses identifier '_Ns', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace Ns {{{$}}
+
+class _Object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '_Object', which is a reserved identifier [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class Object {{{$}}
+  int _Member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '_Member', which is a reserved identifier [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int Member;{{$}}
+};
+
+float _Global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '_Global', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float Global;{{$}}
+
+void _Function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses identifier '_Function', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void Function() {}{{$}}
+
+using _Alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '_Alias', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using Alias = int;{{$}}
+
+template 
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: declaration uses identifier '_TemplateParam', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}template {{$}}
+struct S {};
+
+} // namespace _Ns
+
+//
+
+#define __macro(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses identifier '__macro', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define macro(m) int m = 0{{$}}
+
+namespace __ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses identifier '__ns', which is a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace ns {{{$}}
+class __object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses identifier '__object', which is a reserved identifier [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class _object {{{$}}
+  int __member;
+  // 

[PATCH] D72284: [clang-tidy] Factor out renaming logic from readability-identifier-naming

2020-01-14 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked an inline comment as done.
logan-5 added inline comments.



Comment at: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h:29
+public:
+  RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
+  ~RenamerClangTidyCheck();

njames93 wrote:
> Should this be protected as this class should never be instantiated directly. 
> Also the definition could be moved inline as its just a delegating constructor
The constructor (and destructor) can't be inline, since they need to be able to 
see the specialization of `DenseMapInfo` in the cpp.

I could change it to `protected` to clean up the interface -- though it won't 
strictly change anything, since the class already has pure virtual functions so 
it's not instantiable.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72284/new/

https://reviews.llvm.org/D72284



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


[PATCH] D72284: [clang-tidy] Factor out renaming logic from readability-identifier-naming

2020-01-14 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 238014.
logan-5 added a comment.

Rebased with trunk.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72284/new/

https://reviews.llvm.org/D72284

Files:
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/clang-tidy/utils/CMakeLists.txt
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h

Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
@@ -0,0 +1,150 @@
+//===--- RenamderClangTidyCheck.h - clang-tidy --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+#include 
+#include 
+
+namespace clang {
+
+class MacroInfo;
+
+namespace tidy {
+
+/// Base class for clang-tidy checks that want to flag declarations and/or
+/// macros for renaming based on customizable criteria.
+class RenamerClangTidyCheck : public ClangTidyCheck {
+public:
+  RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
+  ~RenamerClangTidyCheck();
+
+  /// Derived classes should not implement any matching logic themselves; this
+  /// class will do the matching and call the derived class'
+  /// GetDeclFailureInfo() and GetMacroFailureInfo() for determining whether a
+  /// given identifier passes or fails the check.
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override final;
+  void
+  check(const ast_matchers::MatchFinder::MatchResult ) override final;
+  void registerPPCallbacks(const SourceManager , Preprocessor *PP,
+   Preprocessor *ModuleExpanderPP) override final;
+  void onEndOfTranslationUnit() override final;
+
+  /// This enum will be used in %select of the diagnostic message.
+  /// Each value below IgnoreFailureThreshold should have an error message.
+  enum class ShouldFixStatus {
+ShouldFix,
+
+/// The fixup will conflict with a language keyword,
+/// so we can't fix it automatically.
+ConflictsWithKeyword,
+
+/// The fixup will conflict with a macro
+/// definition, so we can't fix it
+/// automatically.
+ConflictsWithMacroDefinition,
+
+/// Values pass this threshold will be ignored completely
+/// i.e no message, no fixup.
+IgnoreFailureThreshold,
+
+/// If the identifier was used or declared within a macro we
+/// won't offer a fixup for safety reasons.
+InsideMacro,
+  };
+
+  /// Information describing a failed check
+  struct FailureInfo {
+std::string KindName; // Tag or misc info to be used as derived classes need
+std::string Fixup;// The name that will be proposed as a fix-it hint
+  };
+
+  /// Holds an identifier name check failure, tracking the kind of the
+  /// identifier, its possible fixup and the starting locations of all the
+  /// identifier usages.
+  struct NamingCheckFailure {
+FailureInfo Info;
+
+/// Whether the failure should be fixed or not.
+///
+/// e.g.: if the identifier was used or declared within a macro we won't
+/// offer a fixup for safety reasons.
+bool ShouldFix() const {
+  return FixStatus == ShouldFixStatus::ShouldFix && !Info.Fixup.empty();
+}
+
+bool ShouldNotify() const {
+  return FixStatus < ShouldFixStatus::IgnoreFailureThreshold;
+}
+
+ShouldFixStatus FixStatus = ShouldFixStatus::ShouldFix;
+
+/// A set of all the identifier usages starting SourceLocation, in
+/// their encoded form.
+llvm::DenseSet RawUsageLocs;
+
+NamingCheckFailure() = default;
+  };
+
+  using NamingCheckId = std::pair;
+
+  using NamingCheckFailureMap =
+  llvm::DenseMap;
+
+  /// Check Macros for style violations.
+  void checkMacro(SourceManager , const Token ,
+  const MacroInfo *MI);
+
+  /// Add a usage of a macro if it already has a violation.
+  void expandMacro(const Token , const MacroInfo *MI);
+
+protected:
+  /// Overridden by derived classes, returns information about if and how a Decl
+  /// failed the check. A 'None' result means the Decl did not fail the check.
+  virtual llvm::Optional
+  GetDeclFailureInfo(const NamedDecl *Decl, const SourceManager ) const = 0;
+
+  /// Overridden by derived classes, returns information about if and 

[PATCH] D72378: [clang-tidy] Add `bugprone-reserved-identifier`

2020-01-10 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 237433.
logan-5 marked 4 inline comments as done.
logan-5 added a comment.

Added a TODO comment for catching more reserved names. Added links in 
documentation to CERT guidelines covered by the check. Pulled strings into 
named constants and made that logic easier to read.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72378/new/

https://reviews.llvm.org/D72378

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h
  clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-reserved-identifier.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-dcl37-c.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-dcl51-cpp.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/system/system-header.h
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/user-header.h
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-c.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-invert.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -0,0 +1,206 @@
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- -- \
+// RUN:   -I%S/Inputs/bugprone-reserved-identifier \
+// RUN:   -isystem %S/Inputs/bugprone-reserved-identifier/system
+
+// no warnings expected without -header-filter=
+#include "user-header.h"
+#include 
+
+#define _MACRO(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '_MACRO', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define MACRO(m) int m = 0{{$}}
+
+namespace _Ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '_Ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace Ns {{{$}}
+
+class _Object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class Object {{{$}}
+  int _Member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int Member;{{$}}
+};
+
+float _Global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float Global;{{$}}
+
+void _Function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '_Function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void Function() {}{{$}}
+
+using _Alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Alias', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using Alias = int;{{$}}
+
+template 
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: declaration uses reserved identifier '_TemplateParam', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}template {{$}}
+struct S {};
+
+} // namespace _Ns
+
+//
+
+#define __macro(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '__macro', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define macro(m) int m = 0{{$}}
+
+namespace __ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '__ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace ns {{{$}}
+class __object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class _object {{{$}}
+  int __member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int _member;{{$}}
+};
+
+float __global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float _global;{{$}}
+
+void __function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: 

[PATCH] D72378: [clang-tidy] Add `bugprone-reserved-identifier`

2020-01-09 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 237244.
logan-5 marked 8 inline comments as done.
logan-5 added a comment.

Addressed nits. Added CERT aliases. Adjusted the check to work for both C and 
C++, including where they differ.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72378/new/

https://reviews.llvm.org/D72378

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h
  clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-reserved-identifier.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-dcl37-c.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-dcl51-cpp.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/system/system-header.h
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/user-header.h
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-c.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-invert.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -0,0 +1,206 @@
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- -- \
+// RUN:   -I%S/Inputs/bugprone-reserved-identifier \
+// RUN:   -isystem %S/Inputs/bugprone-reserved-identifier/system
+
+// no warnings expected without -header-filter=
+#include "user-header.h"
+#include 
+
+#define _MACRO(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '_MACRO', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define MACRO(m) int m = 0{{$}}
+
+namespace _Ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '_Ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace Ns {{{$}}
+
+class _Object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class Object {{{$}}
+  int _Member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int Member;{{$}}
+};
+
+float _Global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float Global;{{$}}
+
+void _Function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '_Function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void Function() {}{{$}}
+
+using _Alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Alias', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using Alias = int;{{$}}
+
+template 
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: declaration uses reserved identifier '_TemplateParam', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}template {{$}}
+struct S {};
+
+} // namespace _Ns
+
+//
+
+#define __macro(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '__macro', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define macro(m) int m = 0{{$}}
+
+namespace __ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '__ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace ns {{{$}}
+class __object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class _object {{{$}}
+  int __member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int _member;{{$}}
+};
+
+float __global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float _global;{{$}}
+
+void __function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '__function', which causes undefined behavior 

[PATCH] D72378: [clang-tidy] Add `bugprone-reserved-identifier`

2020-01-09 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked 2 inline comments as done.
logan-5 added a comment.

In D72378#1810763 , @aaron.ballman 
wrote:

> This check is missing a whole lot of reserved identifiers. For instance, in 
> C++ it is missing everything from http://eel.is/c++draft/zombie.names and for 
> C it is missing everything from future library directions. Are you intending 
> to cover those cases as well?


I admit that those are outside the scope of what I had originally planned for 
this check -- I was primarily concerned about 'uglified' names, and writing a 
check that was 'invertible' in that regard. Now that you mention these, though, 
I do feel like this check doesn't live up to its name without including them.

I'd be interested in incorporating them. It doesn't sound difficult, but it 
does sound like it'd be a sizable addition to this diff. Still familiarizing 
with the workflow around here... would it be alright to leave a TODO comment in 
this patch and add them in an upcoming patch, to keep this one more 
self-contained?




Comment at: 
clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp:48-51
+  if (hasDoubleUnderscore(Name)) {
+Name.consume_front("__");
+return collapseConsecutive(Name, '_');
+  }

aaron.ballman wrote:
> Can't this still result in a reserved identifier? e.g.,
> ```
> int ___Foobar; // three underscores
> ```
`___Foobar` with 3 underscores will be fixed to `_Foobar` by this fixup, which 
is then passed through the underscore capital fixup, and that will be caught 
there. So it still works. 

Thinking about it more, though, I do think the `consume_front` is unnecessary. 
Without it, `__foo` would get changed (by this fixup) to `_foo`, which will be 
corrected by a later fixup if that's still invalid. If not, that's a smaller 
and less opinionated change to the name than the current `__foo` -> `foo`.

I think I'll take out the `consume_front("__")` and update the tests to match.



Comment at: clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h:21
+
+/// Checks for usages of identifiers reserved for use by the C++ 
implementation.
+/// The C++ standard reserves the following names for such use:

aaron.ballman wrote:
> Why just C++? C has reserved identifiers as well, and there's a lot of 
> overlap between the two languages in terms of what's reserved.
That's a good point. I'll do some tweaking to make sure this works well for C, 
including any places where C and C++ differ.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72378/new/

https://reviews.llvm.org/D72378



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


[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-09 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked an inline comment as done.
logan-5 added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp:61
+void templateFunction(T t) {
+  swap(t, t);
+

Quuxplusone wrote:
> logan-5 wrote:
> > Quuxplusone wrote:
> > > This is not the idiomatic way of calling `swap`: there is no ADL swap for 
> > > `int`, for example (so `templateFunction` will hard-error during 
> > > instantiation). It would probably be scope-creep to try to handle the 
> > > "std::swap two-step", but can you leave a TODO comment somewhere to 
> > > revisit this issue?
> > > 
> > I believe this addressed by my juggling the tests around a bit.
> Juggling the tests around doesn't address the fact that any code that does 
> `swap(a,b)` without doing `using std::swap;` first (or `begin(a)` without 
> `using std::begin;`) is almost certainly broken for primitive types.
> 
> My naive thought is that you would //not// do `using std::make_error_code;` 
> because `make_error_code` is definitely never going to be used with primitive 
> types. So "functions okay to call via ADL" and "functions that require the 
> std::swap two-step" actually are slightly different whitelists.
> 
> I was saying that although this issue is probably out-of-scope for what 
> you're doing in this patch, still, it would be nice to leave a TODO 
> somewhere. ...Or maybe you say "nah, that's so far out of scope I don't want 
> to think about it, and it may never get done, so even leaving a TODO is 
> inappropriate."
Thanks for clarifying. I do think that is out of scope for my goals for this 
patch, but I think a TODO comment is reasonable.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282



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


[PATCH] D72378: [clang-tidy] Add `bugprone-reserved-identifier`

2020-01-08 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 236891.
logan-5 marked 3 inline comments as done.
logan-5 added a comment.

Added tests for template parameters.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72378/new/

https://reviews.llvm.org/D72378

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-reserved-identifier.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/system/system-header.h
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/user-header.h
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-invert.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -0,0 +1,206 @@
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- -- \
+// RUN:   -I%S/Inputs/bugprone-reserved-identifier \
+// RUN:   -isystem %S/Inputs/bugprone-reserved-identifier/system
+
+// no warnings expected without -header-filter=
+#include "user-header.h"
+#include 
+
+#define _MACRO(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '_MACRO', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define MACRO(m) int m = 0{{$}}
+
+namespace _Ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '_Ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace Ns {{{$}}
+
+class _Object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class Object {{{$}}
+  int _Member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int Member;{{$}}
+};
+
+float _Global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float Global;{{$}}
+
+void _Function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '_Function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void Function() {}{{$}}
+
+using _Alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Alias', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using Alias = int;{{$}}
+
+template 
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: declaration uses reserved identifier '_TemplateParam', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}template {{$}}
+struct S {};
+
+} // namespace _Ns
+
+//
+
+#define __macro(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '__macro', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define macro(m) int m = 0{{$}}
+
+namespace __ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '__ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace ns {{{$}}
+class __object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class object {{{$}}
+  int __member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int member;{{$}}
+};
+
+float __global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float global;{{$}}
+
+void __function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '__function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void function() {}{{$}}
+
+using __alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__alias', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using alias = int;{{$}}
+
+template 
+// 

[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-08 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 236884.
logan-5 marked 15 inline comments as done.
logan-5 added a comment.

Beefed up tests and split into separate files. Added tests for instantiations 
of template functions that //do// definitely result in ADL, and made the 
warning messages more descriptive in those cases (listing out concrete types of 
arguments in a note).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-generic-lambdas.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl-operators.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
@@ -0,0 +1,160 @@
+// RUN: %check_clang_tidy %s bugprone-unintended-adl %t
+
+namespace aspace {
+struct A {};
+void func(const A &);
+} // namespace aspace
+
+namespace bspace {
+void func(int);
+void test() {
+  aspace::A a;
+  func(5);
+  func(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'aspace::func' through ADL [bugprone-unintended-adl]
+}
+} // namespace bspace
+
+namespace ops {
+
+struct Stream {
+} stream;
+Stream <<(Stream , int) {
+  return s;
+}
+Stream <<(Stream , aspace::A) {
+  return s;
+}
+template 
+IStream >>(IStream , int) {
+  return s;
+}
+template 
+IStream >>(IStream , aspace::A) {
+  return s;
+}
+void smooth_operator(Stream);
+
+} // namespace ops
+
+void ops_test() {
+  ops::stream << 5;
+  // no warning
+  operator<<(ops::stream, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  ops::stream << aspace::A();
+  // no warning
+  operator<<(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+
+  ops::stream >> aspace::A();
+  // no warning
+  operator>>(ops::stream, aspace::A());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator>>' through ADL [bugprone-unintended-adl]
+
+  smooth_operator(ops::stream);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::smooth_operator' through ADL [bugprone-unintended-adl]
+}
+
+namespace std {
+// return types don't matter, returning 'void' everywhere for simplicity
+
+template 
+void swap(T , T );
+template 
+void make_error_code(T);
+template 
+void make_error_condition(T);
+
+template 
+void move(T &&);
+template 
+void forward(T &&);
+
+struct byte {};
+
+} // namespace std
+namespace ns {
+
+struct Swappable {};
+
+// whitelisted
+void swap(Swappable , Swappable );
+void make_error_code(Swappable);
+void make_error_condition(Swappable);
+
+// non-whitelisted
+void move(Swappable);
+void ref(Swappable);
+
+struct Swappable2 {};
+
+} // namespace ns
+struct {
+  template 
+  void operator()(T &&);
+} ref;
+
+void test2() {
+  using namespace std;
+  ns::Swappable a, b;
+  swap(a, b);
+  make_error_code(a);
+  make_error_condition(a);
+  move(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+}
+
+template 
+void foo(T t) {
+  using namespace std;
+  swap(t, t);
+  make_error_code(t);
+  make_error_condition(t);
+
+  move(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+  // CHECK-MESSAGES: [[@LINE-2]]:3: note: with argument type 'struct ns::Swappable'
+  // CHECK-MESSAGES: [[@LINE-3]]:3: warning: unqualified call to 'move' may be resolved through ADL [bugprone-unintended-adl]
+
+  std::swap(t, t);
+  std::move(t);
+
+  ref(t); // function objects bypass ADL, this always calls ::ref
+  ::ref(t);
+}
+
+template 
+void operator<<(T &&, U &&);
+
+template 
+void bar(T t) {
+  t << 5;
+  operator<<(t, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  // CHECK-MESSAGES: [[@LINE-2]]:3: note: with argument types 'struct ops::Stream', 'int'
+  // CHECK-MESSAGES: [[@LINE-3]]:3: warning: unqualified call to 'operator<<' may be resolved through ADL [bugprone-unintended-adl]
+}
+
+void instantiator() {
+  foo(ns::Swappable()); // instantiation will use ADL
+  foo(5);   // instantiation will not use ADL
+
+  bar(ops::Stream()); // instantiation will use ADL
+  

[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-08 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

Hi @Quuxplusone, glad you found your way here. I thought of adding you as a 
reviewer out the gate but then I didn't.




Comment at: clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp:43
+  Whitelist(
+  utils::options::parseStringList(Options.get("Whitelist", "swap"))) {}
+

Quuxplusone wrote:
> JonasToth wrote:
> > JonasToth wrote:
> > > logan-5 wrote:
> > > > JonasToth wrote:
> > > > > do you mean `std::swap`? If you it should be fully qualified.
> > > > > Doesn't `std::error_code` rely on adl, too? I think `std::cout <<` 
> > > > > and other streams of the STL rely on it too, and probably many more 
> > > > > code-constructs that are commonly used.
> > > > > 
> > > > > That means, the list should be extended to at least all 
> > > > > standard-library facilities that basically required ADL to work. And 
> > > > > then we need data on different code bases (e.g. LLVM is a good start) 
> > > > > how much noise gets generated.
> > > > I distinctly //don't// mean `std::swap` -- I want to whitelist any 
> > > > unqualified function call spelled simply `swap`.
> > > > 
> > > > Overloaded operators are the poster child for ADL's usefulness, so 
> > > > that's why this check has a special default-on 
> > > > `IgnoreOverloadedOperators` option. That whitelists a whole ton of 
> > > > legitimate stuff including `std::cout << x` and friends.
> > > > 
> > > > I don't see a ton of discussion online about 
> > > > `error_code`/`make_error_code` and ADL being very much intertwined. I'm 
> > > > not particularly familiar with those constructs myself though, and I 
> > > > could just be out of the loop. I do see a fair number of unqualified 
> > > > calls to `make_error_code` within LLVM, though most of those resolve to 
> > > > `llvm::make_error_code`, the documentation for which says it exists 
> > > > because `std::make_error_code` can't be reliably/portably used with 
> > > > ADL. That makes me think `make_error_code` would belong in LLVM's 
> > > > project-specific whitelist configuration, not the check's default.
> > > > 
> > > > Speaking of which, I did run this check over LLVM while developing and 
> > > > found it not particularly noisy as written. That is, it generated a 
> > > > fair number of warnings, but only on constructs that, when examined 
> > > > closely, //were// a little suspicious or non-obvious.
> > > I don't have a solid understanding of the `error_code` world as well. All 
> > > I know is, that you specialize some templates with your own types in 
> > > order to use the generic `error_code`-world.
> > > AFAIK that needs some form of ADL at some point, but that could even 
> > > happen through the overloaded operators (`==` and `!=`), in which case 
> > > that would already be handled. (maybe @aaron.ballman knows more?)
> > > 
> > > But overloaded operators being ignored by default is good and that point 
> > > is gone :)
> > Yes, `make_error_code` is used via ADL. --> 
> > https://www.boost.org/doc/libs/1_72_0/libs/outcome/doc/html/motivation/plug_error_code.html
> > I think that should be in the default list for ignored functions, as it is 
> > a standard facility.
> +1, both `make_error_code` and `make_error_condition` should be on the 
> whitelist. (I am the author of [P0824 "Summary of SG14 discussion of 
> ``"](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0824r1.html#best-arthur).
>  I also confirm that libc++ `` does call them unqualified on 
> purpose.)
> 
> I would like to see some discussion and/or TODO-comments about the other 
> standard [designated customization 
> points](http://eel.is/c++draft/iterator.range#1.sentence-2): `data`, `begin`, 
> `end`, `rbegin`, `rend`, `crbegin`, `crend`, `size`, `ssize`, and `empty`. 
> This might deserve input from the libc++ implementors.
Added `make_error_condition` to the whitelist.

My inclination would be to just add all those standard customization points to 
the default whitelist. Users can easily supply a smaller whitelist if they want.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp:54
+  move(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' 
through ADL [bugprone-unintended-adl]
+  forward(a);

Quuxplusone wrote:
> This is awesome. :)  Please also consider ADL where there's more than one 
> associated namespace, something like this: https://godbolt.org/z/S73Gzy
> ```
> template struct Templated { };
> Templated testX() {
> Templated x;
> using std::move;
> return move(x);  // "correctly" resolves to std::move today, but still 
> does unintended ADL
> }
> ```
> Please add a test isomorphic to the above, unless you think it's already 
> covered by one of the existing tests.
It's interesting, that code only triggers the check (i.e. my AST matchers only 
think it's doing ADL) without the `using std::move`. I admit I'm a bit confused 
as to 

[PATCH] D72378: [clang-tidy] Add `bugprone-reserved-identifier`

2020-01-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 236754.
logan-5 marked an inline comment as done.
logan-5 added a comment.

Addressed some nits.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72378/new/

https://reviews.llvm.org/D72378

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-reserved-identifier.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/system/system-header.h
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/user-header.h
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-invert.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -0,0 +1,183 @@
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- -- \
+// RUN:   -I%S/Inputs/bugprone-reserved-identifier \
+// RUN:   -isystem %S/Inputs/bugprone-reserved-identifier/system
+
+// no warnings expected without -header-filter=
+#include "user-header.h"
+#include 
+
+#define _MACRO(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '_MACRO', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define MACRO(m) int m = 0{{$}}
+
+namespace _Ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '_Ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace Ns {{{$}}
+
+class _Object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class Object {{{$}}
+  int _Member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int Member;{{$}}
+};
+
+float _Global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float Global;{{$}}
+
+void _Function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '_Function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void Function() {}{{$}}
+
+using _Alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Alias', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using Alias = int;{{$}}
+
+} // namespace _Ns
+
+//
+
+#define __macro(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '__macro', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define macro(m) int m = 0{{$}}
+
+namespace __ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '__ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace ns {{{$}}
+class __object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class object {{{$}}
+  int __member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int member;{{$}}
+};
+
+float __global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float global;{{$}}
+
+void __function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '__function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void function() {}{{$}}
+
+using __alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__alias', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using alias = int;{{$}}
+
+} // namespace __ns
+
+//
+
+#define macro___m(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier 'macro___m', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define macro_m(m) int m = 

[PATCH] D72378: [clang-tidy] Add `bugprone-reserved-identifier`

2020-01-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added reviewers: JonasToth, alexfh, aaron.ballman.
logan-5 added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, xazax.hun, mgorny.
Herald added a project: clang.

This patch adds `bugprone-reserved-identifier`, which flags uses of `__names` 
`_Like` `::_this`, which are reserved for the implementation. The check can 
optionally be inverted, i.e. configured to flag any names that are _not_ 
reserved, which may be useful for e.g. standard library implementors.

This diff is relative to, and dependent on, https://reviews.llvm.org/D72284. 
Not sure if there's a way to chain it or flag it as such within Phabricator, if 
so let me know.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72378

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-reserved-identifier.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/system/system-header.h
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/user-header.h
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-invert.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -0,0 +1,183 @@
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- -- \
+// RUN:   -I%S/Inputs/bugprone-reserved-identifier \
+// RUN:   -isystem %S/Inputs/bugprone-reserved-identifier/system
+
+// no warnings expected without -header-filter=
+#include "user-header.h"
+#include 
+
+#define _MACRO(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '_MACRO', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define MACRO(m) int m = 0{{$}}
+
+namespace _Ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '_Ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace Ns {{{$}}
+
+class _Object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class Object {{{$}}
+  int _Member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int Member;{{$}}
+};
+
+float _Global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float Global;{{$}}
+
+void _Function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '_Function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void Function() {}{{$}}
+
+using _Alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Alias', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using Alias = int;{{$}}
+
+} // namespace _Ns
+
+//
+
+#define __macro(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '__macro', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define macro(m) int m = 0{{$}}
+
+namespace __ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '__ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace ns {{{$}}
+class __object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class object {{{$}}
+  int __member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int member;{{$}}
+};
+
+float __global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float global;{{$}}
+
+void __function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '__function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void function() {}{{$}}
+

[PATCH] D72284: [clang-tidy] Factor out renaming logic from readability-identifier-naming

2020-01-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

(Just in case this got lost in the shuffle) 
If this looks good, (I think) I'll need someone with commit access to help wrap 
it up.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72284/new/

https://reviews.llvm.org/D72284



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


[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked 2 inline comments as done.
logan-5 added a comment.

@JonasToth Thanks for the feedback. Will be updating the diff in the next day 
or so.




Comment at: clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp:89
+
+const auto *Lookup =
+Result.Nodes.getNodeAs("templateADLexpr");

JonasToth wrote:
> Can't you just bind directly to the `unresolvedExpr`?
I need the `"templateADLCall"` node for the diagnostic caret, and the 
`"templateADLexpr"` for the name/spelling of the call. I might totally be 
misunderstanding what you're suggesting here.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp:1
+// RUN: %check_clang_tidy -std=c++14-or-later %s bugprone-unintended-adl %t
+

JonasToth wrote:
> why 14 or later? `ADL` exists in the prior standards, too.
> 
> Additionally we need a test for where overloaded operators are not ignored 
> and create the warnings.
14 or later just because of the generic lambdas in some of the tests. Is it 
worth separating those tests out into their own files so that we don't have to 
pass this flag here?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282



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


[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-07 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 236593.
logan-5 added a comment.

Clean up some false positives in macro expansions and in expressions with 
nested potential ADL usages (e.g. in lambdas passed as function parameters).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
  clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
@@ -0,0 +1,111 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s bugprone-unintended-adl %t
+
+namespace aspace {
+struct A {};
+void func(const A &);
+} // namespace aspace
+
+namespace bspace {
+void func(int);
+void test() {
+  aspace::A a;
+  func(5);
+  func(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'aspace::func' through ADL [bugprone-unintended-adl]
+}
+} // namespace bspace
+
+namespace ops {
+struct Stream {
+} stream;
+Stream <<(Stream , int) {
+  return s;
+}
+void smooth_operator(Stream);
+} // namespace ops
+
+void test() {
+  ops::stream << 5;
+  operator<<(ops::stream, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  smooth_operator(ops::stream);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::smooth_operator' through ADL [bugprone-unintended-adl]
+}
+
+namespace ns {
+struct Swappable {};
+void swap(Swappable , Swappable ); // whitelisted by default
+
+void move(Swappable) {} // non-whitelisted
+template 
+void forward(T) {} // non-whitelisted
+
+struct Swappable2 {};
+} // namespace ns
+
+void move(ns::Swappable2);
+auto ref = [](ns::Swappable2) {};
+
+void test2() {
+  ns::Swappable a, b;
+  using namespace std;
+  swap(a, b);
+  move(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+  forward(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::forward' through ADL [bugprone-unintended-adl]
+}
+
+template 
+void templateFunction(T t) {
+  swap(t, t);
+
+  move(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unqualified call to 'move' may be resolved through ADL [bugprone-unintended-adl]
+
+  ns::move(t);
+  ::move(t);
+
+  ref(t);
+  ::ref(t);
+
+  t << 5;
+  operator<<(t, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unqualified call to 'operator<<' may be resolved through ADL [bugprone-unintended-adl]
+}
+
+namespace std {
+template 
+It find_if(It begin, It end, Pred pred) {
+  for (; begin != end; ++begin) {
+if (pred(*begin))
+  break;
+  }
+  return begin;
+}
+} // namespace std
+
+void test3() {
+  int x = 0;
+  auto l = [&](auto ) { std::find_if(c.begin(), c.end(),
+   [&](auto ) { return e.first == x; }); };
+
+  auto m = [&](auto ) { std::find_if(c.begin(), c.end(),
+   [&](auto ) { return find_if(e, e, x); }); };
+  // CHECK-MESSAGES: [[@LINE-1]]:62: warning: unqualified call to 'find_if' may be resolved through ADL [bugprone-unintended-adl]
+}
+
+template 
+void test4(T t) {
+#define MACRO(x) find_if(x, x, x)
+
+  MACRO(t);
+
+#undef MACRO
+
+#define MACRO(x) func(x)
+
+  MACRO(aspace::A());
+
+#undef MACRO
+}
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
@@ -0,0 +1,47 @@
+.. title:: clang-tidy - bugprone-unintended-adl
+
+bugprone-unintended-adl
+===
+
+Finds usages of ADL (argument-dependent lookup), or potential ADL in the case 
+of templates, that are not on the provided whitelist.
+
+.. code-block:: c++
+
+  namespace aspace {
+  struct A {};
+  void func(const A &);
+  } // namespace aspace
+  
+  namespace bspace {
+  void func(int);
+  void test() {
+aspace::A a;
+func(5);
+func(a); // calls 'aspace::func' through ADL
+  }
+  } // namespace bspace
+
+(Example respectfully borrowed from `Abseil TotW #49 `_.)
+
+ADL can be surprising, and can lead to `subtle bugs 
+`_ without the utmost attention. 
+However, it very is useful for lookup of overloaded operators, and for 
+customization points within libraries (e.g. ``swap`` in the C++ standard 
+library). As such, this check can 

[PATCH] D72284: [clang-tidy] Factor out renaming logic from readability-identifier-naming

2020-01-06 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 236483.
logan-5 marked 3 inline comments as done.
logan-5 added a comment.

Consistent-ified single-statement-body control flow statements to not use 
braces.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72284/new/

https://reviews.llvm.org/D72284

Files:
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/clang-tidy/utils/CMakeLists.txt
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h

Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
@@ -0,0 +1,150 @@
+//===--- RenamderClangTidyCheck.h - clang-tidy --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+#include 
+#include 
+
+namespace clang {
+
+class MacroInfo;
+
+namespace tidy {
+
+/// Base class for clang-tidy checks that want to flag declarations and/or
+/// macros for renaming based on customizable criteria.
+class RenamerClangTidyCheck : public ClangTidyCheck {
+public:
+  RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
+  ~RenamerClangTidyCheck();
+
+  /// Derived classes should not implement any matching logic themselves; this
+  /// class will do the matching and call the derived class'
+  /// GetDeclFailureInfo() and GetMacroFailureInfo() for determining whether a
+  /// given identifier passes or fails the check.
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override final;
+  void
+  check(const ast_matchers::MatchFinder::MatchResult ) override final;
+  void registerPPCallbacks(const SourceManager , Preprocessor *PP,
+   Preprocessor *ModuleExpanderPP) override final;
+  void onEndOfTranslationUnit() override final;
+
+  /// This enum will be used in %select of the diagnostic message.
+  /// Each value below IgnoreFailureThreshold should have an error message.
+  enum class ShouldFixStatus {
+ShouldFix,
+
+/// The fixup will conflict with a language keyword,
+/// so we can't fix it automatically.
+ConflictsWithKeyword,
+
+/// The fixup will conflict with a macro
+/// definition, so we can't fix it
+/// automatically.
+ConflictsWithMacroDefinition,
+
+/// Values pass this threshold will be ignored completely
+/// i.e no message, no fixup.
+IgnoreFailureThreshold,
+
+/// If the identifier was used or declared within a macro we
+/// won't offer a fixup for safety reasons.
+InsideMacro,
+  };
+
+  /// Information describing a failed check
+  struct FailureInfo {
+std::string KindName; // Tag or misc info to be used as derived classes need
+std::string Fixup;// The name that will be proposed as a fix-it hint
+  };
+
+  /// Holds an identifier name check failure, tracking the kind of the
+  /// identifier, its possible fixup and the starting locations of all the
+  /// identifier usages.
+  struct NamingCheckFailure {
+FailureInfo Info;
+
+/// Whether the failure should be fixed or not.
+///
+/// e.g.: if the identifier was used or declared within a macro we won't
+/// offer a fixup for safety reasons.
+bool ShouldFix() const {
+  return FixStatus == ShouldFixStatus::ShouldFix && !Info.Fixup.empty();
+}
+
+bool ShouldNotify() const {
+  return FixStatus < ShouldFixStatus::IgnoreFailureThreshold;
+}
+
+ShouldFixStatus FixStatus = ShouldFixStatus::ShouldFix;
+
+/// A set of all the identifier usages starting SourceLocation, in
+/// their encoded form.
+llvm::DenseSet RawUsageLocs;
+
+NamingCheckFailure() = default;
+  };
+
+  using NamingCheckId = std::pair;
+
+  using NamingCheckFailureMap =
+  llvm::DenseMap;
+
+  /// Check Macros for style violations.
+  void checkMacro(SourceManager , const Token ,
+  const MacroInfo *MI);
+
+  /// Add a usage of a macro if it already has a violation.
+  void expandMacro(const Token , const MacroInfo *MI);
+
+protected:
+  /// Overridden by derived classes, returns information about if and how a Decl
+  /// failed the check. A 'None' result means the Decl did not fail the check.
+  virtual llvm::Optional
+  GetDeclFailureInfo(const NamedDecl *Decl, 

[PATCH] D72284: [clang-tidy] Factor out renaming logic from readability-identifier-naming

2020-01-06 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 236478.
logan-5 marked 3 inline comments as done.
logan-5 added a comment.

More nits.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72284/new/

https://reviews.llvm.org/D72284

Files:
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/clang-tidy/utils/CMakeLists.txt
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h

Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
@@ -0,0 +1,150 @@
+//===--- RenamderClangTidyCheck.h - clang-tidy --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+#include 
+#include 
+
+namespace clang {
+
+class MacroInfo;
+
+namespace tidy {
+
+/// Base class for clang-tidy checks that want to flag declarations and/or
+/// macros for renaming based on customizable criteria.
+class RenamerClangTidyCheck : public ClangTidyCheck {
+public:
+  RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
+  ~RenamerClangTidyCheck();
+
+  /// Derived classes should not implement any matching logic themselves; this
+  /// class will do the matching and call the derived class'
+  /// GetDeclFailureInfo() and GetMacroFailureInfo() for determining whether a
+  /// given identifier passes or fails the check.
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override final;
+  void
+  check(const ast_matchers::MatchFinder::MatchResult ) override final;
+  void registerPPCallbacks(const SourceManager , Preprocessor *PP,
+   Preprocessor *ModuleExpanderPP) override final;
+  void onEndOfTranslationUnit() override final;
+
+  /// This enum will be used in %select of the diagnostic message.
+  /// Each value below IgnoreFailureThreshold should have an error message.
+  enum class ShouldFixStatus {
+ShouldFix,
+
+/// The fixup will conflict with a language keyword,
+/// so we can't fix it automatically.
+ConflictsWithKeyword,
+
+/// The fixup will conflict with a macro
+/// definition, so we can't fix it
+/// automatically.
+ConflictsWithMacroDefinition,
+
+/// Values pass this threshold will be ignored completely
+/// i.e no message, no fixup.
+IgnoreFailureThreshold,
+
+/// If the identifier was used or declared within a macro we
+/// won't offer a fixup for safety reasons.
+InsideMacro,
+  };
+
+  /// Information describing a failed check
+  struct FailureInfo {
+std::string KindName; // Tag or misc info to be used as derived classes need
+std::string Fixup;// The name that will be proposed as a fix-it hint
+  };
+
+  /// Holds an identifier name check failure, tracking the kind of the
+  /// identifier, its possible fixup and the starting locations of all the
+  /// identifier usages.
+  struct NamingCheckFailure {
+FailureInfo Info;
+
+/// Whether the failure should be fixed or not.
+///
+/// e.g.: if the identifier was used or declared within a macro we won't
+/// offer a fixup for safety reasons.
+bool ShouldFix() const {
+  return FixStatus == ShouldFixStatus::ShouldFix && !Info.Fixup.empty();
+}
+
+bool ShouldNotify() const {
+  return FixStatus < ShouldFixStatus::IgnoreFailureThreshold;
+}
+
+ShouldFixStatus FixStatus = ShouldFixStatus::ShouldFix;
+
+/// A set of all the identifier usages starting SourceLocation, in
+/// their encoded form.
+llvm::DenseSet RawUsageLocs;
+
+NamingCheckFailure() = default;
+  };
+
+  using NamingCheckId = std::pair;
+
+  using NamingCheckFailureMap =
+  llvm::DenseMap;
+
+  /// Check Macros for style violations.
+  void checkMacro(SourceManager , const Token ,
+  const MacroInfo *MI);
+
+  /// Add a usage of a macro if it already has a violation.
+  void expandMacro(const Token , const MacroInfo *MI);
+
+protected:
+  /// Overridden by derived classes, returns information about if and how a Decl
+  /// failed the check. A 'None' result means the Decl did not fail the check.
+  virtual llvm::Optional
+  GetDeclFailureInfo(const NamedDecl *Decl, const SourceManager ) const = 0;
+
+  /// Overridden by derived classes, 

[PATCH] D72284: [clang-tidy] Factor out renaming logic from readability-identifier-naming

2020-01-06 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added inline comments.



Comment at: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp:272
+  if (const auto *Typedef =
+  Value->getReturnType().getTypePtr()->getAs()) {
+addUsage(NamingCheckFailures, Typedef->getDecl(),

Eugene.Zelenko wrote:
> Please elide braces.
Would you mind pointing me toward a resource for these formatting nits? I don't 
see anything about requiring omitting braces for single-statement if()s in the 
official LLVM coding standards (and I happen to think the braces actually help 
readability here). If this stuff is explicitly documented somewhere and 
painstakingly enforced like this, I'd rather get it right the first time.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72284/new/

https://reviews.llvm.org/D72284



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


[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-06 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked an inline comment as done.
logan-5 added inline comments.



Comment at: clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp:43
+  Whitelist(
+  utils::options::parseStringList(Options.get("Whitelist", "swap"))) {}
+

JonasToth wrote:
> do you mean `std::swap`? If you it should be fully qualified.
> Doesn't `std::error_code` rely on adl, too? I think `std::cout <<` and other 
> streams of the STL rely on it too, and probably many more code-constructs 
> that are commonly used.
> 
> That means, the list should be extended to at least all standard-library 
> facilities that basically required ADL to work. And then we need data on 
> different code bases (e.g. LLVM is a good start) how much noise gets 
> generated.
I distinctly //don't// mean `std::swap` -- I want to whitelist any unqualified 
function call spelled simply `swap`.

Overloaded operators are the poster child for ADL's usefulness, so that's why 
this check has a special default-on `IgnoreOverloadedOperators` option. That 
whitelists a whole ton of legitimate stuff including `std::cout << x` and 
friends.

I don't see a ton of discussion online about `error_code`/`make_error_code` and 
ADL being very much intertwined. I'm not particularly familiar with those 
constructs myself though, and I could just be out of the loop. I do see a fair 
number of unqualified calls to `make_error_code` within LLVM, though most of 
those resolve to `llvm::make_error_code`, the documentation for which says it 
exists because `std::make_error_code` can't be reliably/portably used with ADL. 
That makes me think `make_error_code` would belong in LLVM's project-specific 
whitelist configuration, not the check's default.

Speaking of which, I did run this check over LLVM while developing and found it 
not particularly noisy as written. That is, it generated a fair number of 
warnings, but only on constructs that, when examined closely, //were// a little 
suspicious or non-obvious.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282



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


[PATCH] D72284: [clang-tidy] Factor out renaming logic from readability-identifier-naming

2020-01-06 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 236449.
logan-5 marked 3 inline comments as done.
logan-5 added a comment.

Addressed some nits. If the rest looks good, I'll need someone with commit 
access to help me wrap this up.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72284/new/

https://reviews.llvm.org/D72284

Files:
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/clang-tidy/utils/CMakeLists.txt
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h

Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
@@ -0,0 +1,145 @@
+//===--- RenamderClangTidyCheck.h - clang-tidy --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+#include 
+#include 
+
+namespace clang {
+
+class MacroInfo;
+
+namespace tidy {
+
+/// Base class for clang-tidy checks that want to flag declarations and/or
+/// macros for renaming based on customizable criteria.
+class RenamerClangTidyCheck : public ClangTidyCheck {
+public:
+  RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
+  ~RenamerClangTidyCheck();
+
+  /// Derived classes should not implement any matching logic themselves; this
+  /// class will do the matching and call the derived class'
+  /// GetDeclFailureInfo() and GetMacroFailureInfo() for determining whether a
+  /// given identifier passes or fails the check.
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override final;
+  void
+  check(const ast_matchers::MatchFinder::MatchResult ) override final;
+  void registerPPCallbacks(const SourceManager , Preprocessor *PP,
+   Preprocessor *ModuleExpanderPP) override final;
+  void onEndOfTranslationUnit() override final;
+
+  /// This enum will be used in %select of the diagnostic message.
+  /// Each value below IgnoreFailureThreshold should have an error message.
+  enum class ShouldFixStatus {
+ShouldFix,
+ConflictsWithKeyword, /// The fixup will conflict with a language keyword,
+  /// so we can't fix it automatically.
+ConflictsWithMacroDefinition, /// The fixup will conflict with a macro
+  /// definition, so we can't fix it
+  /// automatically.
+
+/// Values pass this threshold will be ignored completely
+/// i.e no message, no fixup.
+IgnoreFailureThreshold,
+
+InsideMacro, /// If the identifier was used or declared within a macro we
+ /// won't offer a fixup for safety reasons.
+  };
+
+  /// Information describing a failed check
+  struct FailureInfo {
+std::string KindName; // Tag or misc info to be used as derived classes need
+std::string Fixup;// The name that will be proposed as a fix-it hint
+  };
+
+  /// Holds an identifier name check failure, tracking the kind of the
+  /// identifier, its possible fixup and the starting locations of all the
+  /// identifier usages.
+  struct NamingCheckFailure {
+FailureInfo Info;
+
+/// Whether the failure should be fixed or not.
+///
+/// e.g.: if the identifier was used or declared within a macro we won't
+/// offer a fixup for safety reasons.
+bool ShouldFix() const {
+  return FixStatus == ShouldFixStatus::ShouldFix && !Info.Fixup.empty();
+}
+
+bool ShouldNotify() const {
+  return FixStatus < ShouldFixStatus::IgnoreFailureThreshold;
+}
+
+ShouldFixStatus FixStatus = ShouldFixStatus::ShouldFix;
+
+/// A set of all the identifier usages starting SourceLocation, in
+/// their encoded form.
+llvm::DenseSet RawUsageLocs;
+
+NamingCheckFailure() = default;
+  };
+
+  typedef std::pair NamingCheckId;
+
+  typedef llvm::DenseMap
+  NamingCheckFailureMap;
+
+  /// Check Macros for style violations.
+  void checkMacro(SourceManager , const Token ,
+  const MacroInfo *MI);
+
+  /// Add a usage of a macro if it already has a violation.
+  void expandMacro(const Token , const MacroInfo *MI);
+
+protected:
+  /// Overridden by derived classes, returns information about if and how a Decl
+  /// failed the check. A 'None' result means the 

[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-06 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 236420.
logan-5 marked 5 inline comments as done.
logan-5 added a comment.

Addressed some formatting stuff.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
  clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
@@ -0,0 +1,75 @@
+// RUN: %check_clang_tidy %s bugprone-unintended-adl %t
+
+namespace aspace {
+struct A {};
+void func(const A &);
+} // namespace aspace
+
+namespace bspace {
+void func(int);
+void test() {
+  aspace::A a;
+  func(5);
+  func(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'aspace::func' through ADL [bugprone-unintended-adl]
+}
+} // namespace bspace
+
+namespace ops {
+struct Stream {
+} stream;
+Stream <<(Stream , int) {
+  return s;
+}
+void smooth_operator(Stream);
+} // namespace ops
+
+void test() {
+  ops::stream << 5;
+  operator<<(ops::stream, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  smooth_operator(ops::stream);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::smooth_operator' through ADL [bugprone-unintended-adl]
+}
+
+namespace ns {
+struct Swappable {};
+void swap(Swappable , Swappable ); // whitelisted by default
+
+void move(Swappable) {} // non-whitelisted
+template 
+void forward(T) {} // non-whitelisted
+
+struct Swappable2 {};
+} // namespace ns
+
+void move(ns::Swappable2);
+auto ref = [](ns::Swappable2) {};
+
+void test2() {
+  ns::Swappable a, b;
+  using namespace std;
+  swap(a, b);
+  move(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+  forward(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::forward' through ADL [bugprone-unintended-adl]
+}
+
+template 
+void templateFunction(T t) {
+  swap(t, t);
+
+  move(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unqualified call to 'move' may be resolved through ADL [bugprone-unintended-adl]
+
+  ns::move(t);
+  ::move(t);
+
+  ref(t);
+  ::ref(t);
+
+  t << 5;
+  operator<<(t, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unqualified call to 'operator<<' may be resolved through ADL [bugprone-unintended-adl]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
@@ -0,0 +1,47 @@
+.. title:: clang-tidy - bugprone-unintended-adl
+
+bugprone-unintended-adl
+===
+
+Finds usages of ADL (argument-dependent lookup), or potential ADL in the case 
+of templates, that are not on the provided whitelist.
+
+.. code-block:: c++
+
+  namespace aspace {
+  struct A {};
+  void func(const A &);
+  } // namespace aspace
+  
+  namespace bspace {
+  void func(int);
+  void test() {
+aspace::A a;
+func(5);
+func(a); // calls 'aspace::func' through ADL
+  }
+  } // namespace bspace
+
+(Example respectfully borrowed from `Abseil TotW #49 `_.)
+
+ADL can be surprising, and can lead to `subtle bugs 
+`_ without the utmost attention. 
+However, it very is useful for lookup of overloaded operators, and for 
+customization points within libraries (e.g. ``swap`` in the C++ standard 
+library). As such, this check can be configured to ignore calls to overloaded 
+operators as well as other legitimate uses of ADL specified in a whitelist.
+
+This check does not suggest any fixes.
+
+Options
+---
+
+.. option:: IgnoreOverloadedOperators
+
+   If non-zero, ignores calls to overloaded operators using operator syntax 
+   (e.g. ``a + b``), but not function call syntax (e.g. ``operator+(a, b)``). 
+   Default is `1`.
+
+.. option:: Whitelist
+
+   Semicolon-separated list of names that the check ignores. Default is `swap`.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -104,6 +104,12 @@
   
   Violating the naming rules above results in undefined behavior.
 
+- New :doc:`bugprone-unintended-adl
+  ` check.
+
+  Finds usages of ADL (argument-dependent 

[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-06 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added inline comments.



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst:35
+
+   If non-zero, ignores calls to overloaded operators using the operator 
syntax (e.g. `a + b`), but not the function call syntax (e.g. `operator+(a, 
b)`). Default is `1`.
+

Eugene.Zelenko wrote:
> Indentation. Please use double back-ticks for a + b and operator+(a, b).
I'm not sure what you would like me to change about the indentation. This 
follows the same format (three spaces) I've found in the documentation for 
other checks.



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst:39
+
+   Semicolon-separated list of names that the check ignores. Default is `swap`.

Eugene.Zelenko wrote:
> Indentation. Please use double back-ticks for swap (or std::swap?).
Since the 'swap' here is referring to the default value of the option string, 
shouldn't it just be single backticks?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72282/new/

https://reviews.llvm.org/D72282



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


[PATCH] D72213: [clang-tidy] Add `bugprone-reserved-identifier` to flag usages of reserved C++ names

2020-01-06 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added a comment.

I'm taking @JonasToth's suggestion and splitting this into two patches, one for 
the refactor, followed by one for the new check. The refactor patch is here: 
https://reviews.llvm.org/D72284. Thanks everyone for your feedback so far.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72213/new/

https://reviews.llvm.org/D72213



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


[PATCH] D72284: [clang-tidy] Factor out renaming logic from readability-identifier-naming

2020-01-06 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added reviewers: alexfh, hokein, aaron.ballman.
logan-5 added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, xazax.hun, mgorny.
Herald added a project: clang.

Before this patch, `readability-identifier-naming` contained a significant 
amount of logic for (a) checking the style of identifiers, followed by (b) 
renaming/applying fix-its. This patch factors out (b) into a separate base 
class so that it can be reused by other checks that want to do renaming. This 
also cleans up `readability-identifier-naming` significantly, since now it only 
needs to be concerned with the interesting details of (a).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72284

Files:
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/clang-tidy/utils/CMakeLists.txt
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h

Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
@@ -0,0 +1,145 @@
+//===--- RenamderClangTidyCheck.h - clang-tidy --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+#include 
+#include 
+
+namespace clang {
+
+class MacroInfo;
+
+namespace tidy {
+
+/// Base class for clang-tidy checks that want to flag declarations and/or
+/// macros for renaming based on customizable criteria.
+class RenamerClangTidyCheck : public ClangTidyCheck {
+public:
+  RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
+  ~RenamerClangTidyCheck();
+
+  /// Derived classes should not implement any matching logic themselves; this
+  /// class will do the matching and call the derived class'
+  /// GetDeclFailureInfo() and GetMacroFailureInfo() for determining whether a
+  /// given identifier passes or fails the check.
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override final;
+  void
+  check(const ast_matchers::MatchFinder::MatchResult ) override final;
+  void registerPPCallbacks(const SourceManager , Preprocessor *PP,
+   Preprocessor *ModuleExpanderPP) override final;
+  void onEndOfTranslationUnit() override final;
+
+  /// This enum will be used in %select of the diagnostic message.
+  /// Each value below IgnoreFailureThreshold should have an error message.
+  enum class ShouldFixStatus {
+ShouldFix,
+ConflictsWithKeyword, /// The fixup will conflict with a language keyword,
+  /// so we can't fix it automatically.
+ConflictsWithMacroDefinition, /// The fixup will conflict with a macro
+  /// definition, so we can't fix it
+  /// automatically.
+
+/// Values pass this threshold will be ignored completely
+/// i.e no message, no fixup.
+IgnoreFailureThreshold,
+
+InsideMacro, /// If the identifier was used or declared within a macro we
+ /// won't offer a fixup for safety reasons.
+  };
+
+  /// Information describing a failed check
+  struct FailureInfo {
+std::string KindName; // Tag or misc info to be used as derived classes need
+std::string Fixup;// The name that will be proposed as a fix-it hint
+  };
+
+  /// Holds an identifier name check failure, tracking the kind of the
+  /// identifier, its possible fixup and the starting locations of all the
+  /// identifier usages.
+  struct NamingCheckFailure {
+FailureInfo Info;
+
+/// Whether the failure should be fixed or not.
+///
+/// e.g.: if the identifier was used or declared within a macro we won't
+/// offer a fixup for safety reasons.
+bool ShouldFix() const {
+  return FixStatus == ShouldFixStatus::ShouldFix && !Info.Fixup.empty();
+}
+
+bool ShouldNotify() const {
+  return FixStatus < ShouldFixStatus::IgnoreFailureThreshold;
+}
+
+ShouldFixStatus FixStatus = ShouldFixStatus::ShouldFix;
+
+/// A set of all the identifier usages starting SourceLocation, in
+/// their encoded form.
+llvm::DenseSet RawUsageLocs;
+
+NamingCheckFailure() = default;
+  };
+
+  typedef std::pair NamingCheckId;
+
+  typedef llvm::DenseMap
+  NamingCheckFailureMap;
+
+  /// Check Macros 

[PATCH] D72282: [clang-tidy] Add `bugprone-unintended-adl`

2020-01-06 Thread Logan Smith via Phabricator via cfe-commits
logan-5 created this revision.
logan-5 added reviewers: aaron.ballman, hokein, alexfh.
logan-5 added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, xazax.hun, mgorny.
Herald added a project: clang.

This patch adds `bugprone-unintended-adl` which flags uses of ADL that are not 
on the provided whitelist.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72282

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UnintendedADLCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
  clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unintended-adl.cpp
@@ -0,0 +1,75 @@
+// RUN: %check_clang_tidy %s bugprone-unintended-adl %t
+
+namespace aspace {
+struct A {};
+void func(const A &);
+} // namespace aspace
+
+namespace bspace {
+void func(int);
+void test() {
+  aspace::A a;
+  func(5);
+  func(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'aspace::func' through ADL [bugprone-unintended-adl]
+}
+} // namespace bspace
+
+namespace ops {
+struct Stream {
+} stream;
+Stream <<(Stream , int) {
+  return s;
+}
+void smooth_operator(Stream);
+} // namespace ops
+
+void test() {
+  ops::stream << 5;
+  operator<<(ops::stream, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::operator<<' through ADL [bugprone-unintended-adl]
+  smooth_operator(ops::stream);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ops::smooth_operator' through ADL [bugprone-unintended-adl]
+}
+
+namespace ns {
+struct Swappable {};
+void swap(Swappable , Swappable ); // whitelisted by default
+
+void move(Swappable) {} // non-whitelisted
+template 
+void forward(T) {} // non-whitelisted
+
+struct Swappable2 {};
+} // namespace ns
+
+void move(ns::Swappable2);
+auto ref = [](ns::Swappable2) {};
+
+void test2() {
+  ns::Swappable a, b;
+  using namespace std;
+  swap(a, b);
+  move(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::move' through ADL [bugprone-unintended-adl]
+  forward(a);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expression calls 'ns::forward' through ADL [bugprone-unintended-adl]
+}
+
+template 
+void templateFunction(T t) {
+  swap(t, t);
+
+  move(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unqualified call to 'move' may be resolved through ADL [bugprone-unintended-adl]
+
+  ns::move(t);
+  ::move(t);
+
+  ref(t);
+  ::ref(t);
+
+  t << 5;
+  operator<<(t, 5);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unqualified call to 'operator<<' may be resolved through ADL [bugprone-unintended-adl]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone-unintended-adl.rst
@@ -0,0 +1,39 @@
+.. title:: clang-tidy - bugprone-unintended-adl
+
+bugprone-unintended-adl
+===
+
+Finds usages of ADL (argument-dependent lookup), or potential ADL in the case of templates, that are not on the provided whitelist.
+
+.. code-block:: c++
+
+  namespace aspace {
+  struct A {};
+  void func(const A &);
+  } // namespace aspace
+  
+  namespace bspace {
+  void func(int);
+  void test() {
+aspace::A a;
+func(5);
+func(a); // calls 'aspace::func' through ADL
+  }
+  } // namespace bspace
+
+(Example respectfully borrowed from `Abseil TotW #49 `_.)
+
+ADL can be surprising, and can lead to `subtle bugs `_ without the utmost attention. However, it very is useful for lookup of overloaded operators, and for customization points within libraries (e.g. `swap` in the C++ standard library). As such, this check can be configured to ignore calls to overloaded operators as well as other legitimate uses of ADL specified in a whitelist.
+
+This check does not suggest any fixes.
+
+Options
+---
+
+.. option:: IgnoreOverloadedOperators
+
+   If non-zero, ignores calls to overloaded operators using the operator syntax (e.g. `a + b`), but not the function call syntax (e.g. `operator+(a, b)`). Default is `1`.
+
+.. option:: Whitelist
+
+   Semicolon-separated list of names that the check ignores. Default is `swap`.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -104,6 +104,12 @@
   
   Violating the naming rules above results in undefined behavior.
 
+- 

[PATCH] D72213: [clang-tidy] Add `bugprone-reserved-identifier` to flag usages of reserved C++ names

2020-01-04 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 236216.
logan-5 added a comment.

Change double-underscore fix-it finding algorithm to correctly collapse any 
number of >=2 underscores in a row, not just exactly 2 (or multiples of 2).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72213/new/

https://reviews.llvm.org/D72213

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/clang-tidy/utils/CMakeLists.txt
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-reserved-identifier.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/system/system-header.h
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/user-header.h
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-invert.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -0,0 +1,183 @@
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- -- \
+// RUN:   -I%S/Inputs/bugprone-reserved-identifier \
+// RUN:   -isystem %S/Inputs/bugprone-reserved-identifier/system
+
+// no warnings expected without -header-filter=
+#include "user-header.h"
+#include 
+
+#define _MACRO(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '_MACRO', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define MACRO(m) int m = 0{{$}}
+
+namespace _Ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '_Ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace Ns {{{$}}
+
+class _Object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class Object {{{$}}
+  int _Member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int Member;{{$}}
+};
+
+float _Global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float Global;{{$}}
+
+void _Function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '_Function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void Function() {}{{$}}
+
+using _Alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Alias', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using Alias = int;{{$}}
+
+} // namespace _Ns
+
+//
+
+#define __macro(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '__macro', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define macro(m) int m = 0{{$}}
+
+namespace __ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '__ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace ns {{{$}}
+class __object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class object {{{$}}
+  int __member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int member;{{$}}
+};
+
+float __global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float global;{{$}}
+
+void __function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '__function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void function() {}{{$}}
+
+using __alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__alias', which causes 

[PATCH] D72213: [clang-tidy] Add `bugprone-reserved-identifier` to flag usages of reserved C++ names

2020-01-04 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked an inline comment as done.
logan-5 added inline comments.



Comment at: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h:59
+  struct FailureInfo {
+std::string KindName; // Tag or misc info to be used as derived classes 
need
+std::string Fixup;// The name that will be proposed as a fix-it hint

JonasToth wrote:
> I think the `kind` should be an enum instead of stringly typing.
I can't disagree that the string is a little gross, but since the 
interpretation of the string is for use by the derived classes, I don't think 
an enum is flexible enough.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72213/new/

https://reviews.llvm.org/D72213



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


[PATCH] D72213: [clang-tidy] Add `bugprone-reserved-identifier` to flag usages of reserved C++ names

2020-01-04 Thread Logan Smith via Phabricator via cfe-commits
logan-5 updated this revision to Diff 236210.
logan-5 marked 39 inline comments as done.
logan-5 added a comment.

Addressed formatting issues, and tweaked handling of the names `__` and `::_`: 
the check now flags these but doesn't suggest a fix.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72213/new/

https://reviews.llvm.org/D72213

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/clang-tidy/utils/CMakeLists.txt
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone-reserved-identifier.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/system/system-header.h
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-reserved-identifier/user-header.h
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-invert.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -0,0 +1,179 @@
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- -- \
+// RUN:   -I%S/Inputs/bugprone-reserved-identifier \
+// RUN:   -isystem %S/Inputs/bugprone-reserved-identifier/system
+
+// no warnings expected without -header-filter=
+#include "user-header.h"
+#include 
+
+#define _MACRO(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '_MACRO', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define MACRO(m) int m = 0{{$}}
+
+namespace _Ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '_Ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace Ns {{{$}}
+
+class _Object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class Object {{{$}}
+  int _Member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int Member;{{$}}
+};
+
+float _Global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float Global;{{$}}
+
+void _Function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '_Function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void Function() {}{{$}}
+
+using _Alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '_Alias', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}using Alias = int;{{$}}
+
+} // namespace _Ns
+
+//
+
+#define __macro(m) int m = 0
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: declaration uses reserved identifier '__macro', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}#define macro(m) int m = 0{{$}}
+
+namespace __ns {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration uses reserved identifier '__ns', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}namespace ns {{{$}}
+class __object {
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__object', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}class object {{{$}}
+  int __member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__member', which causes undefined behavior [bugprone-reserved-identifier]
+  // CHECK-FIXES: {{^}}  int member;{{$}}
+};
+
+float __global;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier '__global', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}float global;{{$}}
+
+void __function() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration uses reserved identifier '__function', which causes undefined behavior [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}void function() {}{{$}}
+
+using __alias = int;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration uses reserved identifier 

[PATCH] D72213: [clang-tidy] Add `bugprone-reserved-identifier` to flag usages of reserved C++ names

2020-01-04 Thread Logan Smith via Phabricator via cfe-commits
logan-5 marked an inline comment as done.
logan-5 added a comment.

@Eugene.Zelenko never mind about pushing back on the nits; I had misread some 
of them. They all sound good, will address.




Comment at: clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp:70
+  const bool IsInGlobalNamespace) {
+  return IsInGlobalNamespace && Name.size() > 1 && Name[0] == '_';
+}

Mordante wrote:
> `Name.size() > 1` doesn't catch `_` in the global namespace. Catching `_` 
> will probably also cause issues with the automatic renaming.
> What about renaming `__`?
Good point. Perhaps the check should catch these but simply not propose a fix.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp:68
+
+} // namespace __ns
+

Mordante wrote:
> Should it not suggest to change this to `namespace ns` ?
That's a fair point. I'll point out (again) that this is an existing case 
missed by the logic factored out of readability-identifier-naming, so it might 
be better suited for a separate patch?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72213/new/

https://reviews.llvm.org/D72213



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


[PATCH] D72213: [clang-tidy] Add `bugprone-reserved-identifier` to flag usages of reserved C++ names

2020-01-04 Thread Logan Smith via Phabricator via cfe-commits
logan-5 added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier-invert.cpp:21
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration uses identifier 
'Helper', which is not a reserved identifier [bugprone-reserved-identifier]
+// CHECK-FIXES: {{^}}struct __Helper {};{{$}}
+struct _helper2 {};

Mordante wrote:
> Why suggesting `__Helper` instead of  `_Helper` ?
I mostly didn't see a reason to make the check opinionated on //how// to uglify 
names, though I suppose now that you mention it, a smaller change to the name 
when possible is arguably better.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72213/new/

https://reviews.llvm.org/D72213



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


  1   2   >