[PATCH] D147395: [Clangd] Make the type hint length limit configurable

2023-04-08 Thread Yi Zhang via Phabricator via cfe-commits
zhangyi1357 updated this revision to Diff 511955.
zhangyi1357 marked an inline comment as done.
zhangyi1357 added a comment.

Combine mutiple commits into single one


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147395

Files:
  clang-tools-extra/clangd/Config.h
  clang-tools-extra/clangd/ConfigCompile.cpp
  clang-tools-extra/clangd/ConfigFragment.h
  clang-tools-extra/clangd/ConfigYAML.cpp
  clang-tools-extra/clangd/InlayHints.cpp
  clang-tools-extra/clangd/unittests/InlayHintTests.cpp

Index: clang-tools-extra/clangd/unittests/InlayHintTests.cpp
===
--- clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -1324,6 +1324,21 @@
 // Omit type hint past a certain length (currently 32)
 auto var = foo();
   )cpp");
+
+  Config Cfg;
+  Cfg.InlayHints.TypeNameLimit = 0;
+  WithContextValue WithCfg(Config::Key, std::move(Cfg));
+
+  assertTypeHints(
+  R"cpp(
+template 
+struct A {};
+struct MultipleWords {};
+A foo();
+// Should have type hint with TypeNameLimit = 0
+auto $var[[var]] = foo();
+  )cpp",
+  ExpectedHint{": A", "var"});
 }
 
 TEST(TypeHints, DefaultTemplateArgs) {
Index: clang-tools-extra/clangd/InlayHints.cpp
===
--- clang-tools-extra/clangd/InlayHints.cpp
+++ clang-tools-extra/clangd/InlayHints.cpp
@@ -688,7 +688,8 @@
   return;
 
 std::string TypeName = T.getAsString(Policy);
-if (TypeName.length() < TypeNameLimit)
+if (Cfg.InlayHints.TypeNameLimit == 0 ||
+TypeName.length() < Cfg.InlayHints.TypeNameLimit)
   addInlayHint(R, HintSide::Right, InlayHintKind::Type, Prefix, TypeName,
/*Suffix=*/"");
   }
@@ -714,8 +715,6 @@
   // the policies are initialized for more details.)
   PrintingPolicy TypeHintPolicy;
   PrintingPolicy StructuredBindingPolicy;
-
-  static const size_t TypeNameLimit = 32;
 };
 
 } // namespace
Index: clang-tools-extra/clangd/ConfigYAML.cpp
===
--- clang-tools-extra/clangd/ConfigYAML.cpp
+++ clang-tools-extra/clangd/ConfigYAML.cpp
@@ -254,6 +254,10 @@
   if (auto Value = boolValue(N, "Designators"))
 F.Designators = *Value;
 });
+Dict.handle("TypeNameLimit", [&](Node ) {
+  if (auto Value = uint32Value(N, "TypeNameLimit"))
+F.TypeNameLimit = *Value;
+});
 Dict.parse(N);
   }
 
@@ -375,6 +379,17 @@
 return std::nullopt;
   }
 
+  std::optional> uint32Value(Node , llvm::StringRef Desc) {
+if (auto Scalar = scalarValue(N, Desc)) {
+  unsigned long long Num;
+  if (!llvm::getAsUnsignedInteger(**Scalar, 0, Num)) {
+return Located(Num, Scalar->Range);
+  }
+}
+warning(Desc + " invalid number", N);
+return std::nullopt;
+  }
+
   // Try to parse a list of single scalar values, or just a single value.
   std::optional>> scalarValues(Node ) {
 std::vector> Result;
Index: clang-tools-extra/clangd/ConfigFragment.h
===
--- clang-tools-extra/clangd/ConfigFragment.h
+++ clang-tools-extra/clangd/ConfigFragment.h
@@ -322,6 +322,8 @@
 std::optional> DeducedTypes;
 /// Show designators in aggregate initialization.
 std::optional> Designators;
+/// Limit the length of type name hints. (0 means no limit)
+std::optional> TypeNameLimit;
   };
   InlayHintsBlock InlayHints;
 };
Index: clang-tools-extra/clangd/ConfigCompile.cpp
===
--- clang-tools-extra/clangd/ConfigCompile.cpp
+++ clang-tools-extra/clangd/ConfigCompile.cpp
@@ -611,6 +611,11 @@
   Out.Apply.push_back([Value(**F.Designators)](const Params &, Config ) {
 C.InlayHints.Designators = Value;
   });
+if (F.TypeNameLimit)
+  Out.Apply.push_back(
+  [Value(**F.TypeNameLimit)](const Params &, Config ) {
+C.InlayHints.TypeNameLimit = Value;
+  });
   }
 
   constexpr static llvm::SourceMgr::DiagKind Error = llvm::SourceMgr::DK_Error;
Index: clang-tools-extra/clangd/Config.h
===
--- clang-tools-extra/clangd/Config.h
+++ clang-tools-extra/clangd/Config.h
@@ -147,6 +147,8 @@
 bool Parameters = true;
 bool DeducedTypes = true;
 bool Designators = true;
+// Limit the length of type names in inlay hints. (0 means no limit)
+uint32_t TypeNameLimit = 32;
   } InlayHints;
 };
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147395: [Clangd] Make the type hint length limit configurable

2023-04-08 Thread Yi Zhang via Phabricator via cfe-commits
zhangyi1357 updated this revision to Diff 511950.
zhangyi1357 marked 2 inline comments as done.
zhangyi1357 added a comment.

- [Clangd] Remove unneccessary modification


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147395

Files:
  clang-tools-extra/clangd/Config.h
  clang-tools-extra/clangd/ConfigCompile.cpp
  clang-tools-extra/clangd/ConfigFragment.h
  clang-tools-extra/clangd/ConfigYAML.cpp
  clang-tools-extra/clangd/InlayHints.cpp
  clang-tools-extra/clangd/unittests/InlayHintTests.cpp

Index: clang-tools-extra/clangd/unittests/InlayHintTests.cpp
===
--- clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -1324,6 +1324,21 @@
 // Omit type hint past a certain length (currently 32)
 auto var = foo();
   )cpp");
+
+  Config Cfg;
+  Cfg.InlayHints.TypeNameLimit = 0;
+  WithContextValue WithCfg(Config::Key, std::move(Cfg));
+
+  assertTypeHints(
+  R"cpp(
+template 
+struct A {};
+struct MultipleWords {};
+A foo();
+// Should have type hint with TypeNameLimit = 0
+auto $var[[var]] = foo();
+  )cpp",
+  ExpectedHint{": A", "var"});
 }
 
 TEST(TypeHints, DefaultTemplateArgs) {
Index: clang-tools-extra/clangd/InlayHints.cpp
===
--- clang-tools-extra/clangd/InlayHints.cpp
+++ clang-tools-extra/clangd/InlayHints.cpp
@@ -688,7 +688,8 @@
   return;
 
 std::string TypeName = T.getAsString(Policy);
-if (TypeName.length() < TypeNameLimit)
+if (Cfg.InlayHints.TypeNameLimit == 0 ||
+TypeName.length() < Cfg.InlayHints.TypeNameLimit)
   addInlayHint(R, HintSide::Right, InlayHintKind::Type, Prefix, TypeName,
/*Suffix=*/"");
   }
@@ -714,8 +715,6 @@
   // the policies are initialized for more details.)
   PrintingPolicy TypeHintPolicy;
   PrintingPolicy StructuredBindingPolicy;
-
-  static const size_t TypeNameLimit = 32;
 };
 
 } // namespace
Index: clang-tools-extra/clangd/ConfigYAML.cpp
===
--- clang-tools-extra/clangd/ConfigYAML.cpp
+++ clang-tools-extra/clangd/ConfigYAML.cpp
@@ -254,6 +254,10 @@
   if (auto Value = boolValue(N, "Designators"))
 F.Designators = *Value;
 });
+Dict.handle("TypeNameLimit", [&](Node ) {
+  if (auto Value = uint32Value(N, "TypeNameLimit"))
+F.TypeNameLimit = *Value;
+});
 Dict.parse(N);
   }
 
@@ -375,6 +379,17 @@
 return std::nullopt;
   }
 
+  std::optional> uint32Value(Node , llvm::StringRef Desc) {
+if (auto Scalar = scalarValue(N, Desc)) {
+  unsigned long long Num;
+  if (!llvm::getAsUnsignedInteger(**Scalar, 0, Num)) {
+return Located(Num, Scalar->Range);
+  }
+}
+warning(Desc + " invalid number", N);
+return std::nullopt;
+  }
+
   // Try to parse a list of single scalar values, or just a single value.
   std::optional>> scalarValues(Node ) {
 std::vector> Result;
Index: clang-tools-extra/clangd/ConfigFragment.h
===
--- clang-tools-extra/clangd/ConfigFragment.h
+++ clang-tools-extra/clangd/ConfigFragment.h
@@ -322,6 +322,8 @@
 std::optional> DeducedTypes;
 /// Show designators in aggregate initialization.
 std::optional> Designators;
+/// Limit the length of type name hints. (0 means no limit)
+std::optional> TypeNameLimit;
   };
   InlayHintsBlock InlayHints;
 };
Index: clang-tools-extra/clangd/ConfigCompile.cpp
===
--- clang-tools-extra/clangd/ConfigCompile.cpp
+++ clang-tools-extra/clangd/ConfigCompile.cpp
@@ -611,6 +611,11 @@
   Out.Apply.push_back([Value(**F.Designators)](const Params &, Config ) {
 C.InlayHints.Designators = Value;
   });
+if (F.TypeNameLimit)
+  Out.Apply.push_back(
+  [Value(**F.TypeNameLimit)](const Params &, Config ) {
+C.InlayHints.TypeNameLimit = Value;
+  });
   }
 
   constexpr static llvm::SourceMgr::DiagKind Error = llvm::SourceMgr::DK_Error;
Index: clang-tools-extra/clangd/Config.h
===
--- clang-tools-extra/clangd/Config.h
+++ clang-tools-extra/clangd/Config.h
@@ -147,6 +147,8 @@
 bool Parameters = true;
 bool DeducedTypes = true;
 bool Designators = true;
+// Limit the length of type names in inlay hints. (0 means no limit)
+uint32_t TypeNameLimit = 32;
   } InlayHints;
 };
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147867: [Windows SEH] Fix ehcleanup crash for Windows -EHa

2023-04-08 Thread Phoebe Wang via Phabricator via cfe-commits
pengfei created this revision.
pengfei added reviewers: tentzen, efriedma, LuoYuanke, jyu2.
Herald added subscribers: kbarton, nemanjai.
Herald added a project: All.
pengfei requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

`Builder.GetInsertBlock()` may return null sometimes. 
https://godbolt.org/z/n1Ph47jP1


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147867

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchReturn.cpp


Index: clang/test/CodeGen/windows-seh-EHa-CppCatchReturn.cpp
===
--- clang/test/CodeGen/windows-seh-EHa-CppCatchReturn.cpp
+++ clang/test/CodeGen/windows-seh-EHa-CppCatchReturn.cpp
@@ -12,3 +12,20 @@
   return;
   }
 }
+
+__declspec(noreturn) void bar();
+class baz {
+public:
+  ~baz();
+};
+
+// CHECK: define dso_local void @"?qux@@YAXXZ
+// CHECK: invoke void @llvm.seh.scope.begin()
+// CHECK-NOT: llvm.seh.try
+// CHECK-NOT: llvm.seh.scope.end
+
+// FIXME: We may need to generate llvm.seh.scope.end or remove 
llvm.seh.scope.begin.
+void qux() {
+  baz a;
+  bar();
+}
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -782,7 +782,7 @@
   if (!RequiresNormalCleanup) {
 // Mark CPP scope end for passed-by-value Arg temp
 //   per Windows ABI which is "normally" Cleanup in callee
-if (IsEHa && getInvokeDest()) {
+if (IsEHa && getInvokeDest() && Builder.GetInsertBlock()) {
   if (Personality.isMSVCXXPersonality())
 EmitSehCppScopeEnd();
 }
@@ -1031,6 +1031,8 @@
 if (!Personality.isMSVCPersonality()) {
   EHStack.pushTerminate();
   PushedTerminate = true;
+} else if (IsEHa && getInvokeDest()) {
+  EmitSehCppScopeEnd();
 }
 
 // We only actually emit the cleanup code if the cleanup is either


Index: clang/test/CodeGen/windows-seh-EHa-CppCatchReturn.cpp
===
--- clang/test/CodeGen/windows-seh-EHa-CppCatchReturn.cpp
+++ clang/test/CodeGen/windows-seh-EHa-CppCatchReturn.cpp
@@ -12,3 +12,20 @@
   return;
   }
 }
+
+__declspec(noreturn) void bar();
+class baz {
+public:
+  ~baz();
+};
+
+// CHECK: define dso_local void @"?qux@@YAXXZ
+// CHECK: invoke void @llvm.seh.scope.begin()
+// CHECK-NOT: llvm.seh.try
+// CHECK-NOT: llvm.seh.scope.end
+
+// FIXME: We may need to generate llvm.seh.scope.end or remove llvm.seh.scope.begin.
+void qux() {
+  baz a;
+  bar();
+}
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -782,7 +782,7 @@
   if (!RequiresNormalCleanup) {
 // Mark CPP scope end for passed-by-value Arg temp
 //   per Windows ABI which is "normally" Cleanup in callee
-if (IsEHa && getInvokeDest()) {
+if (IsEHa && getInvokeDest() && Builder.GetInsertBlock()) {
   if (Personality.isMSVCXXPersonality())
 EmitSehCppScopeEnd();
 }
@@ -1031,6 +1031,8 @@
 if (!Personality.isMSVCPersonality()) {
   EHStack.pushTerminate();
   PushedTerminate = true;
+} else if (IsEHa && getInvokeDest()) {
+  EmitSehCppScopeEnd();
 }
 
 // We only actually emit the cleanup code if the cleanup is either
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147857: [clang-tidy] fix false positve for namespace with attrs in modernize-concat-nested-namespaces

2023-04-08 Thread Congcong Cai via Phabricator via cfe-commits
HerrCai0907 added a comment.

It should fix https://github.com/llvm/llvm-project/issues/57530 due to side 
effect instead of root cause.\


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147857

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


[PATCH] D147857: [clang-tidy] fix false positve for namespace with attrs in modernize-concat-nested-namespaces

2023-04-08 Thread Congcong Cai via Phabricator via cfe-commits
HerrCai0907 created this revision.
HerrCai0907 added a reviewer: PiotrZSL.
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a reviewer: njames93.
Herald added a project: All.
HerrCai0907 requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

add pre check to avoid false positive for namespace with attributes like

  namespace [[deprecated]] ns {}


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147857

Files:
  clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
===
--- 
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
@@ -21,11 +21,17 @@
 } // namespace n2
 
 namespace n5 {
-inline namespace n6 {
+inline namespace inline_ns {
 void t();
-}
+} // namespace inline_ns
 } // namespace n5
 
+namespace n6 {
+namespace [[deprecated]] attr_ns {
+void t();
+} // namespace attr_ns
+} // namespace n6
+
 namespace n7 {
 void t();
 
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -305,6 +305,10 @@
   ` when using macro 
between
   namespace declarations could result incorrect fix.
 
+- Fixed an false positive in :doc:`modernize-concat-nested-namespaces
+  ` when using namespace 
with 
+  attributes.
+
 - Fixed a false positive in :doc:`performance-no-automatic-move
   ` when warning would be
   emitted for a const local variable to which NRVO is applied.
Index: clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
@@ -31,8 +31,9 @@
   return Lexer::getSourceText(TextRange, Sources, LangOpts);
 }
 
-static bool anonymousOrInlineNamespace(const NamespaceDecl ) {
-  return ND.isAnonymousNamespace() || ND.isInlineNamespace();
+static bool unsupportedNamespace(const NamespaceDecl ) {
+  return ND.isAnonymousNamespace() || ND.isInlineNamespace() ||
+ !ND.attrs().empty();
 }
 
 static bool singleNamedNamespaceChild(const NamespaceDecl ) {
@@ -41,7 +42,7 @@
 return false;
 
   const auto *ChildNamespace = dyn_cast(*Decls.begin());
-  return ChildNamespace && !anonymousOrInlineNamespace(*ChildNamespace);
+  return ChildNamespace && !unsupportedNamespace(*ChildNamespace);
 }
 
 static bool alreadyConcatenated(std::size_t NumCandidates,
@@ -166,7 +167,7 @@
   if (!locationsInSameFile(Sources, ND.getBeginLoc(), ND.getRBraceLoc()))
 return;
 
-  if (anonymousOrInlineNamespace(ND))
+  if (unsupportedNamespace(ND))
 return;
 
   Namespaces.push_back();


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
@@ -21,11 +21,17 @@
 } // namespace n2
 
 namespace n5 {
-inline namespace n6 {
+inline namespace inline_ns {
 void t();
-}
+} // namespace inline_ns
 } // namespace n5
 
+namespace n6 {
+namespace [[deprecated]] attr_ns {
+void t();
+} // namespace attr_ns
+} // namespace n6
+
 namespace n7 {
 void t();
 
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -305,6 +305,10 @@
   ` when using macro between
   namespace declarations could result incorrect fix.
 
+- Fixed an false positive in :doc:`modernize-concat-nested-namespaces
+  ` when using namespace with 
+  attributes.
+
 - Fixed a false positive in :doc:`performance-no-automatic-move
   ` when warning would be
   emitted for a const local variable to which NRVO is applied.
Index: clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
@@ -31,8 +31,9 @@
   return Lexer::getSourceText(TextRange, Sources, LangOpts);
 }
 
-static bool anonymousOrInlineNamespace(const NamespaceDecl ) {
-  return ND.isAnonymousNamespace() || ND.isInlineNamespace();
+static bool unsupportedNamespace(const NamespaceDecl ) {
+  

[PATCH] D147843: [clang-tidy] fix hint use correct range to replace last NamespaceDecl

2023-04-08 Thread Congcong Cai via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0f9b71d11b91: [clang-tidy] fix hint use correct range to 
replace last NamespaceDecl (authored by HerrCai0907).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147843

Files:
  clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
===
--- 
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
@@ -105,7 +105,7 @@
 namespace n28 {
 namespace n29::n30 {
 // CHECK-MESSAGES-DAG: :[[@LINE-3]]:1: warning: nested namespaces can be 
concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES: namespace n26::n27::n28::n29::n30
+// CHECK-FIXES: namespace n26::n27::n28::n29::n30 {
 void t() {}
 } // namespace n29::n30
 } // namespace n28
Index: clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
@@ -124,12 +124,12 @@
   SmallVector Backs;
   Backs.reserve(Namespaces.size());
 
-  NamespaceDecl const *LastND = nullptr;
+  NamespaceDecl const *LastNonNestND = nullptr;
 
   for (const NamespaceDecl *ND : Namespaces) {
 if (ND->isNested())
   continue;
-LastND = ND;
+LastNonNestND = ND;
 std::optional SR =
 getCleanedNamespaceFrontRange(ND, SM, LangOpts);
 if (!SR.has_value())
@@ -137,7 +137,7 @@
 Fronts.push_back(SR.value());
 Backs.push_back(getCleanedNamespaceBackRange(ND, SM, LangOpts));
   }
-  if (LastND == nullptr || Fronts.empty() || Backs.empty())
+  if (LastNonNestND == nullptr || Fronts.empty() || Backs.empty())
 return;
   // the last one should be handled specially
   Fronts.pop_back();
@@ -147,9 +147,11 @@
   for (SourceRange const  : Fronts)
 DB << FixItHint::CreateRemoval(Front);
   DB << FixItHint::CreateReplacement(
-  SourceRange{LastND->getBeginLoc(), LastND->getLocation()},
+  SourceRange{LastNonNestND->getBeginLoc(),
+  Namespaces.back()->getLocation()},
   ConcatNameSpace);
-  if (LastRBrace != SourceRange{LastND->getRBraceLoc(), 
LastND->getRBraceLoc()})
+  if (LastRBrace !=
+  SourceRange{LastNonNestND->getRBraceLoc(), 
LastNonNestND->getRBraceLoc()})
 DB << FixItHint::CreateReplacement(LastRBrace,
("} // " + ConcatNameSpace).str());
   for (SourceRange const  : llvm::reverse(Backs))


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
@@ -105,7 +105,7 @@
 namespace n28 {
 namespace n29::n30 {
 // CHECK-MESSAGES-DAG: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES: namespace n26::n27::n28::n29::n30
+// CHECK-FIXES: namespace n26::n27::n28::n29::n30 {
 void t() {}
 } // namespace n29::n30
 } // namespace n28
Index: clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
@@ -124,12 +124,12 @@
   SmallVector Backs;
   Backs.reserve(Namespaces.size());
 
-  NamespaceDecl const *LastND = nullptr;
+  NamespaceDecl const *LastNonNestND = nullptr;
 
   for (const NamespaceDecl *ND : Namespaces) {
 if (ND->isNested())
   continue;
-LastND = ND;
+LastNonNestND = ND;
 std::optional SR =
 getCleanedNamespaceFrontRange(ND, SM, LangOpts);
 if (!SR.has_value())
@@ -137,7 +137,7 @@
 Fronts.push_back(SR.value());
 Backs.push_back(getCleanedNamespaceBackRange(ND, SM, LangOpts));
   }
-  if (LastND == nullptr || Fronts.empty() || Backs.empty())
+  if (LastNonNestND == nullptr || Fronts.empty() || Backs.empty())
 return;
   // the last one should be handled specially
   Fronts.pop_back();
@@ -147,9 +147,11 @@
   for (SourceRange const  : Fronts)
 DB << FixItHint::CreateRemoval(Front);
   DB << FixItHint::CreateReplacement(
-  SourceRange{LastND->getBeginLoc(), LastND->getLocation()},
+  SourceRange{LastNonNestND->getBeginLoc(),
+  Namespaces.back()->getLocation()},
   

[clang-tools-extra] 0f9b71d - [clang-tidy] fix hint use correct range to replace last NamespaceDecl

2023-04-08 Thread Congcong Cai via cfe-commits

Author: Congcong Cai
Date: 2023-04-08T21:03:59+02:00
New Revision: 0f9b71d11b91d6fb7fa678a12327bafbc43605b5

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

LOG: [clang-tidy] fix hint use correct range to replace last NamespaceDecl

range of replacing last namespace decl should be from last non nested namespace 
to last namespace

Reviewed By: PiotrZSL

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp

clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
index d89b0a9165e88..e18dcc2b3e591 100644
--- a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
@@ -124,12 +124,12 @@ void ConcatNestedNamespacesCheck::reportDiagnostic(
   SmallVector Backs;
   Backs.reserve(Namespaces.size());
 
-  NamespaceDecl const *LastND = nullptr;
+  NamespaceDecl const *LastNonNestND = nullptr;
 
   for (const NamespaceDecl *ND : Namespaces) {
 if (ND->isNested())
   continue;
-LastND = ND;
+LastNonNestND = ND;
 std::optional SR =
 getCleanedNamespaceFrontRange(ND, SM, LangOpts);
 if (!SR.has_value())
@@ -137,7 +137,7 @@ void ConcatNestedNamespacesCheck::reportDiagnostic(
 Fronts.push_back(SR.value());
 Backs.push_back(getCleanedNamespaceBackRange(ND, SM, LangOpts));
   }
-  if (LastND == nullptr || Fronts.empty() || Backs.empty())
+  if (LastNonNestND == nullptr || Fronts.empty() || Backs.empty())
 return;
   // the last one should be handled specially
   Fronts.pop_back();
@@ -147,9 +147,11 @@ void ConcatNestedNamespacesCheck::reportDiagnostic(
   for (SourceRange const  : Fronts)
 DB << FixItHint::CreateRemoval(Front);
   DB << FixItHint::CreateReplacement(
-  SourceRange{LastND->getBeginLoc(), LastND->getLocation()},
+  SourceRange{LastNonNestND->getBeginLoc(),
+  Namespaces.back()->getLocation()},
   ConcatNameSpace);
-  if (LastRBrace != SourceRange{LastND->getRBraceLoc(), 
LastND->getRBraceLoc()})
+  if (LastRBrace !=
+  SourceRange{LastNonNestND->getRBraceLoc(), 
LastNonNestND->getRBraceLoc()})
 DB << FixItHint::CreateReplacement(LastRBrace,
("} // " + ConcatNameSpace).str());
   for (SourceRange const  : llvm::reverse(Backs))

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
index a67c279ddd765..7728ada6a18db 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
@@ -105,7 +105,7 @@ namespace n26::n27 {
 namespace n28 {
 namespace n29::n30 {
 // CHECK-MESSAGES-DAG: :[[@LINE-3]]:1: warning: nested namespaces can be 
concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES: namespace n26::n27::n28::n29::n30
+// CHECK-FIXES: namespace n26::n27::n28::n29::n30 {
 void t() {}
 } // namespace n29::n30
 } // namespace n28



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


[PATCH] D147175: [clang] Add __is_trivially_equality_comparable

2023-04-08 Thread Mark de Wever via Phabricator via cfe-commits
Mordante added inline comments.



Comment at: libcxx/include/__type_traits/is_equality_comparable.h:46
 template 
-struct __is_trivially_equality_comparable
+struct __libcpp_is_trivially_equality_comparable
 : integral_constant Mordante wrote:
> > This does not magically use the builtin right? Does the patch miss that 
> > parts that use the builtin or is that a followup? If it's a followup I 
> > would prefer move the libc++ code changes of this patch to a separate 
> > review.
> No, it doesn't magically use the builtin. I plan to do that in a follow-up. 
> These changes are required though, since clang grabs the name with this patch.
But it would still be possible to have these libc++ changes in a separate 
review and commit them separately. I would say the libc++ changes are quite 
trivial and can be landed quite quickly.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147175

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


[PATCH] D146904: [clang-tidy] Fix extern fixes in readability-redundant-declaration

2023-04-08 Thread Piotr Zegar via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd8c948cfe4ef: [clang-tidy] Fix extern fixes in 
readability-redundant-declaration (authored by PiotrZSL).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146904

Files:
  clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
===
--- 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
+++ 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
@@ -120,3 +120,9 @@
 // CHECK-MESSAGES-NOMSCOMPAT: :[[@LINE-1]]:20: warning: redundant 'g' 
declaration
 // CHECK-FIXES-NOMSCOMPAT: {{^}}// extern g{{$}}
 #endif
+
+// PR42068
+extern "C" int externX;
+int dummyBeforeBegin;extern "C" int externX;int dummyAfterEnd;
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: redundant 'externX' declaration 
[readability-redundant-declaration]
+// CHECK-FIXES: {{^}}int dummyBeforeBegin;int dummyAfterEnd;{{$}}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -275,6 +275,10 @@
   ` check when warning 
would
   be unnecessarily emitted for template dependent ``if constexpr``.
 
+- Fixed incorrect fixes in :doc:`readability-redundant-declaration
+  ` check when linkage
+  (like ``extern "C"``) is explicitly specified.
+
 - Improved :doc:`readability-static-accessed-through-instance
   ` check to
   support unscoped enumerations through instances and fixed usage of anonymous
@@ -298,7 +302,7 @@
   ``DISABLED_`` in the test suite name.
 
 - Fixed an issue in :doc:`modernize-concat-nested-namespaces
-  ` when using macro 
between 
+  ` when using macro 
between
   namespace declarations could result incorrect fix.
 
 - Fixed a false positive in :doc:`performance-no-automatic-move
Index: clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
@@ -35,7 +35,8 @@
   functionDecl(unless(anyOf(
   isDefinition(), isDefaulted(),
   doesDeclarationForceExternallyVisibleDefinition(),
-  hasAncestor(friendDecl()))
+  hasAncestor(friendDecl()),
+optionally(hasParent(linkageSpecDecl().bind("extern"
   .bind("Decl"),
   this);
 }
@@ -78,9 +79,17 @@
   D->getSourceRange().getEnd(), 0, SM, Result.Context->getLangOpts());
   {
 auto Diag = diag(D->getLocation(), "redundant %0 declaration") << D;
-if (!MultiVar && !DifferentHeaders)
-  Diag << FixItHint::CreateRemoval(
-  SourceRange(D->getSourceRange().getBegin(), EndLoc));
+if (!MultiVar && !DifferentHeaders) {
+  SourceLocation BeginLoc;
+  if (const auto *Extern =
+  Result.Nodes.getNodeAs("extern");
+  Extern && !Extern->hasBraces())
+BeginLoc = Extern->getExternLoc();
+  else
+BeginLoc = D->getSourceRange().getBegin();
+
+  Diag << FixItHint::CreateRemoval(SourceRange(BeginLoc, EndLoc));
+}
   }
   diag(Prev->getLocation(), "previously declared here", DiagnosticIDs::Note);
 }


Index: clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
@@ -120,3 +120,9 @@
 // CHECK-MESSAGES-NOMSCOMPAT: :[[@LINE-1]]:20: warning: redundant 'g' declaration
 // CHECK-FIXES-NOMSCOMPAT: {{^}}// extern g{{$}}
 #endif
+
+// PR42068
+extern "C" int externX;
+int dummyBeforeBegin;extern "C" int externX;int dummyAfterEnd;
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: redundant 'externX' declaration [readability-redundant-declaration]
+// CHECK-FIXES: {{^}}int dummyBeforeBegin;int dummyAfterEnd;{{$}}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -275,6 +275,10 @@
   ` check when warning would
   be unnecessarily emitted for template dependent ``if constexpr``.
 
+- Fixed incorrect fixes in :doc:`readability-redundant-declaration
+  ` check when linkage
+  (like ``extern 

[clang-tools-extra] d8c948c - [clang-tidy] Fix extern fixes in readability-redundant-declaration

2023-04-08 Thread Piotr Zegar via cfe-commits

Author: Piotr Zegar
Date: 2023-04-08T17:17:12Z
New Revision: d8c948cfe4eff814a2be71e74cbd835e9be28865

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

LOG: [clang-tidy] Fix extern fixes in readability-redundant-declaration

Currently check does not look into LinkageSpecDecl
when removing redundant variable re-declarations.
This were leaving code in non-compiling state.
Fix patch fixes this and adds removal also of 'extern C'.

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

Reviewed By: carlosgalvezp

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

Added: 


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

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

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
index f21f0a785689f..7850a6f29995f 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
@@ -35,7 +35,8 @@ void RedundantDeclarationCheck::registerMatchers(MatchFinder 
*Finder) {
   functionDecl(unless(anyOf(
   isDefinition(), isDefaulted(),
   doesDeclarationForceExternallyVisibleDefinition(),
-  hasAncestor(friendDecl()))
+  hasAncestor(friendDecl()),
+optionally(hasParent(linkageSpecDecl().bind("extern"
   .bind("Decl"),
   this);
 }
@@ -78,9 +79,17 @@ void RedundantDeclarationCheck::check(const 
MatchFinder::MatchResult ) {
   D->getSourceRange().getEnd(), 0, SM, Result.Context->getLangOpts());
   {
 auto Diag = diag(D->getLocation(), "redundant %0 declaration") << D;
-if (!MultiVar && !DifferentHeaders)
-  Diag << FixItHint::CreateRemoval(
-  SourceRange(D->getSourceRange().getBegin(), EndLoc));
+if (!MultiVar && !DifferentHeaders) {
+  SourceLocation BeginLoc;
+  if (const auto *Extern =
+  Result.Nodes.getNodeAs("extern");
+  Extern && !Extern->hasBraces())
+BeginLoc = Extern->getExternLoc();
+  else
+BeginLoc = D->getSourceRange().getBegin();
+
+  Diag << FixItHint::CreateRemoval(SourceRange(BeginLoc, EndLoc));
+}
   }
   diag(Prev->getLocation(), "previously declared here", DiagnosticIDs::Note);
 }

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index ba041bca86c66..1ab7f4c79c7df 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -275,6 +275,10 @@ Changes in existing checks
   ` check when warning 
would
   be unnecessarily emitted for template dependent ``if constexpr``.
 
+- Fixed incorrect fixes in :doc:`readability-redundant-declaration
+  ` check when linkage
+  (like ``extern "C"``) is explicitly specified.
+
 - Improved :doc:`readability-static-accessed-through-instance
   ` check to
   support unscoped enumerations through instances and fixed usage of anonymous
@@ -298,7 +302,7 @@ Changes in existing checks
   ``DISABLED_`` in the test suite name.
 
 - Fixed an issue in :doc:`modernize-concat-nested-namespaces
-  ` when using macro 
between 
+  ` when using macro 
between
   namespace declarations could result incorrect fix.
 
 - Fixed a false positive in :doc:`performance-no-automatic-move

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
index 85ee9a52dfb7e..395839ec3f6f3 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
@@ -120,3 +120,9 @@ extern inline void g(); // extern g
 // CHECK-MESSAGES-NOMSCOMPAT: :[[@LINE-1]]:20: warning: redundant 'g' 
declaration
 // CHECK-FIXES-NOMSCOMPAT: {{^}}// extern g{{$}}
 #endif
+
+// PR42068
+extern "C" int externX;
+int dummyBeforeBegin;extern "C" int externX;int dummyAfterEnd;
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: redundant 'externX' declaration 
[readability-redundant-declaration]
+// CHECK-FIXES: {{^}}int dummyBeforeBegin;int dummyAfterEnd;{{$}}



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


[PATCH] D144036: [clang-tidy] Add bugprone-non-zero-enum-to-bool-conversion check

2023-04-08 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL updated this revision to Diff 511904.
PiotrZSL marked an inline comment as done.
PiotrZSL retitled this revision from "[clang-tidy] Add 
bugprone-enum-to-bool-conversion check" to "[clang-tidy] Add 
bugprone-non-zero-enum-to-bool-conversion check".
PiotrZSL added a comment.

Review fixes + check rename


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144036

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone/non-zero-enum-to-bool-conversion.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion-cpp11.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion.cpp
@@ -0,0 +1,107 @@
+// RUN: %check_clang_tidy -std=c++98-or-later %s bugprone-non-zero-enum-to-bool-conversion %t -- \
+// RUN:   -config="{CheckOptions: [{key: bugprone-non-zero-enum-to-bool-conversion.EnumIgnoreList, value: '::without::issue::IgnoredEnum;IgnoredSecondEnum'}]}"
+
+namespace with::issue {
+
+typedef enum EStatus {
+  SUCCESS   = 1,
+  FAILURE   = 2,
+  INVALID_PARAM = 3,
+  UNKNOWN   = 4
+} Status;
+
+bool testEnumConversion(EStatus value) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:10: warning: conversion of 'EStatus' into 'bool' will always return 'true', enum doesn't have a zero-value enumerator [bugprone-non-zero-enum-to-bool-conversion]
+  return value;
+}
+
+bool testTypedefConversion(Status value) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:10: warning: conversion of 'EStatus' into 'bool' will always return 'true', enum doesn't have a zero-value enumerator [bugprone-non-zero-enum-to-bool-conversion]
+  return value;
+}
+
+bool testExplicitConversion(EStatus value) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:28: warning: conversion of 'EStatus' into 'bool' will always return 'true', enum doesn't have a zero-value enumerator [bugprone-non-zero-enum-to-bool-conversion]
+  return static_cast(value);
+}
+
+bool testInIfConversion(EStatus value) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: conversion of 'EStatus' into 'bool' will always return 'true', enum doesn't have a zero-value enumerator [bugprone-non-zero-enum-to-bool-conversion]
+  if (value) {
+return false;
+  }
+  return true;
+}
+
+bool testWithNegation(EStatus value) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: conversion of 'EStatus' into 'bool' will always return 'true', enum doesn't have a zero-value enumerator [bugprone-non-zero-enum-to-bool-conversion]
+  return not value;
+}
+
+}
+
+namespace without::issue {
+
+enum StatusWithZero {
+  UNK  = 0,
+  OK   = 1,
+  NOT_OK = 2
+};
+
+bool testEnumConversion(StatusWithZero value) {
+  return value;
+}
+
+enum WithDefault {
+  Value0,
+  Value1
+};
+
+bool testEnumConversion(WithDefault value) {
+  return value;
+}
+
+enum WithNegative : int {
+  Nen2 = -2,
+  Nen1,
+  Nen0
+};
+
+bool testEnumConversion(WithNegative value) {
+  return value;
+}
+
+enum EStatus {
+  SUCCESS = 1,
+  FAILURE,
+  INVALID_PARAM,
+  UNKNOWN
+};
+
+bool explicitCompare(EStatus value) {
+  return value == SUCCESS;
+}
+
+bool testEnumeratorCompare() {
+  return SUCCESS;
+}
+
+enum IgnoredEnum {
+  IGNORED_VALUE_1 = 1,
+  IGNORED_VALUE_2
+};
+
+enum IgnoredSecondEnum {
+  IGNORED_SECOND_VALUE_1 = 1,
+  IGNORED_SECOND_VALUE_2
+};
+
+bool testIgnored(IgnoredEnum value) {
+  return value;
+}
+
+bool testIgnored(IgnoredSecondEnum value) {
+  return value;
+}
+
+}
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion-cpp11.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion-cpp11.cpp
@@ -0,0 +1,110 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s bugprone-non-zero-enum-to-bool-conversion %t
+
+namespace with::issue {
+
+enum class EStatusC : char {
+  SUCCESS   = 1,
+  FAILURE   = 2,
+  INVALID_PARAM = 3,
+  UNKNOWN   = 4
+};
+
+bool testEnumConversion(EStatusC value) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:10: warning: conversion of 'EStatusC' into 'bool' will always return 'true', enum doesn't have a zero-value enumerator [bugprone-non-zero-enum-to-bool-conversion]
+  return static_cast(value);
+}
+
+enum class EStatusS : short {
+  SUCCESS   = 1,
+  FAILURE   = 2,
+  

[PATCH] D144036: [clang-tidy] Add bugprone-enum-to-bool-conversion check

2023-04-08 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL marked 14 inline comments as done.
PiotrZSL added inline comments.



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/bugprone/enum-to-bool-conversion.rst:12-13
+
+The check produces false positives if the ``enum`` is used to store other 
values
+(used as a bit-mask or zero-initialized on purpose). To deal with 
false-positives,
+``//NOLINT`` or casting first to the underlying type before casting to ``bool``

carlosgalvezp wrote:
> I can't think of a case where this could happen, might be worth adding an 
> example below.
I thinkg that in STL we got some enums (flags) used as bitmasks... Just wanted 
to mention that there could be some known false-positives.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144036

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


[PATCH] D146904: [clang-tidy] Fix extern fixes in readability-redundant-declaration

2023-04-08 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp accepted this revision.
carlosgalvezp added a comment.
This revision is now accepted and ready to land.

Looks great, thanks!




Comment at: 
clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp:86
+  Result.Nodes.getNodeAs("extern");
+  Extern && !Extern->hasBraces())
+BeginLoc = Extern->getExternLoc();

PiotrZSL wrote:
> carlosgalvezp wrote:
> > This can be removed, leaving it as:
> > 
> > ```
> > if (const auto *Extern = ... && !Extern->hasBraces())
> > ```
> If you mean:
> ```
>  if (const auto *Extern =
>   Result.Nodes.getNodeAs("extern");
>   !Extern->hasBraces())
> 
> 
> then no, it cannot be like this because Extern can be null.
You are right, this can only be done when there's no other conditions in the 
`if`!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146904

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


[PATCH] D146904: [clang-tidy] Fix extern fixes in readability-redundant-declaration

2023-04-08 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL updated this revision to Diff 511901.
PiotrZSL added a comment.

Added release notes, fixed typo.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146904

Files:
  clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
===
--- 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
+++ 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
@@ -120,3 +120,9 @@
 // CHECK-MESSAGES-NOMSCOMPAT: :[[@LINE-1]]:20: warning: redundant 'g' 
declaration
 // CHECK-FIXES-NOMSCOMPAT: {{^}}// extern g{{$}}
 #endif
+
+// PR42068
+extern "C" int externX;
+int dummyBeforeBegin;extern "C" int externX;int dummyAfterEnd;
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: redundant 'externX' declaration 
[readability-redundant-declaration]
+// CHECK-FIXES: {{^}}int dummyBeforeBegin;int dummyAfterEnd;{{$}}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -275,6 +275,10 @@
   ` check when warning 
would
   be unnecessarily emitted for template dependent ``if constexpr``.
 
+- Fixed incorrect fixes in :doc:`readability-redundant-declaration
+  ` check when linkage
+  (like ``extern "C"``) is explicitly specified.
+
 - Improved :doc:`readability-static-accessed-through-instance
   ` check to
   support unscoped enumerations through instances and fixed usage of anonymous
@@ -298,7 +302,7 @@
   ``DISABLED_`` in the test suite name.
 
 - Fixed an issue in :doc:`modernize-concat-nested-namespaces
-  ` when using macro 
between 
+  ` when using macro 
between
   namespace declarations could result incorrect fix.
 
 - Fixed a false positive in :doc:`performance-no-automatic-move
Index: clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
@@ -35,7 +35,8 @@
   functionDecl(unless(anyOf(
   isDefinition(), isDefaulted(),
   doesDeclarationForceExternallyVisibleDefinition(),
-  hasAncestor(friendDecl()))
+  hasAncestor(friendDecl()),
+optionally(hasParent(linkageSpecDecl().bind("extern"
   .bind("Decl"),
   this);
 }
@@ -78,9 +79,17 @@
   D->getSourceRange().getEnd(), 0, SM, Result.Context->getLangOpts());
   {
 auto Diag = diag(D->getLocation(), "redundant %0 declaration") << D;
-if (!MultiVar && !DifferentHeaders)
-  Diag << FixItHint::CreateRemoval(
-  SourceRange(D->getSourceRange().getBegin(), EndLoc));
+if (!MultiVar && !DifferentHeaders) {
+  SourceLocation BeginLoc;
+  if (const auto *Extern =
+  Result.Nodes.getNodeAs("extern");
+  Extern && !Extern->hasBraces())
+BeginLoc = Extern->getExternLoc();
+  else
+BeginLoc = D->getSourceRange().getBegin();
+
+  Diag << FixItHint::CreateRemoval(SourceRange(BeginLoc, EndLoc));
+}
   }
   diag(Prev->getLocation(), "previously declared here", DiagnosticIDs::Note);
 }


Index: clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp
@@ -120,3 +120,9 @@
 // CHECK-MESSAGES-NOMSCOMPAT: :[[@LINE-1]]:20: warning: redundant 'g' declaration
 // CHECK-FIXES-NOMSCOMPAT: {{^}}// extern g{{$}}
 #endif
+
+// PR42068
+extern "C" int externX;
+int dummyBeforeBegin;extern "C" int externX;int dummyAfterEnd;
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: redundant 'externX' declaration [readability-redundant-declaration]
+// CHECK-FIXES: {{^}}int dummyBeforeBegin;int dummyAfterEnd;{{$}}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -275,6 +275,10 @@
   ` check when warning would
   be unnecessarily emitted for template dependent ``if constexpr``.
 
+- Fixed incorrect fixes in :doc:`readability-redundant-declaration
+  ` check when linkage
+  (like ``extern "C"``) is explicitly specified.
+
 - Improved 

[PATCH] D147714: [Attr] Introduce [[clang::nonportable_musttail]] as less strict version of [[clang::musttail]]

2023-04-08 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added a comment.

>> I'm curious if folks have pursued @efriedma 's suggestion #2 from 
>> https://github.com/llvm/llvm-project/issues/54964#issuecomment-1101612886?

This is something we mentioned here, perform target specific checks in Sema 
(but still it is not possible to catch everything in Sema!)

But the problem of strict musttail call maker stays here. So either we have to 
relax musttail or create new one.


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

https://reviews.llvm.org/D147714

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


[PATCH] D146904: [clang-tidy] Fix extern fixes in readability-redundant-declaration

2023-04-08 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp:86
+  Result.Nodes.getNodeAs("extern");
+  Extern && !Extern->hasBraces())
+BeginLoc = Extern->getExternLoc();

carlosgalvezp wrote:
> This can be removed, leaving it as:
> 
> ```
> if (const auto *Extern = ... && !Extern->hasBraces())
> ```
If you mean:
```
 if (const auto *Extern =
  Result.Nodes.getNodeAs("extern");
  !Extern->hasBraces())


then no, it cannot be like this because Extern can be null.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146904

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


[PATCH] D146904: [clang-tidy] Fix extern fixes in readability-redundant-declaration

2023-04-08 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp:126
+extern "C" int externX;
+int dumyBegin;extern "C" int externX;int dummyEnd;
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: redundant 'externX' declaration 
[readability-redundant-declaration]

carlosgalvezp wrote:
> Typo: dummy
> 
> I don't quite see why these are needed to test the example in PR42068?
I wasn't sure about getLocForEndOfToken, so just wanted to add some tokens 
before and after, to be 100% sure that they wont be removed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146904

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


[PATCH] D144331: [libc++][format] Implements formatter thread::id.

2023-04-08 Thread Mark de Wever via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG88622aabf107: [libc++][format] Implements formatter 
thread::id. (authored by Mordante).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144331

Files:
  libcxx/docs/FeatureTestMacroTable.rst
  libcxx/docs/ReleaseNotes.rst
  libcxx/docs/Status/Cxx2b.rst
  libcxx/docs/Status/Cxx2bPapers.csv
  libcxx/docs/Status/FormatPaper.csv
  libcxx/include/__format/parser_std_format_spec.h
  libcxx/include/__threading_support
  libcxx/include/thread
  libcxx/include/version
  libcxx/test/libcxx/transitive_includes/cxx03.csv
  libcxx/test/libcxx/transitive_includes/cxx11.csv
  libcxx/test/libcxx/transitive_includes/cxx14.csv
  libcxx/test/libcxx/transitive_includes/cxx17.csv
  libcxx/test/libcxx/transitive_includes/cxx20.csv
  libcxx/test/libcxx/transitive_includes/cxx2b.csv
  
libcxx/test/std/language.support/support.limits/support.limits.general/thread.version.compile.pass.cpp
  
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.format.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.tests.h
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.vformat.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/parse.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
  
libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
  libcxx/utils/generate_feature_test_macro_components.py

Index: libcxx/utils/generate_feature_test_macro_components.py
===
--- libcxx/utils/generate_feature_test_macro_components.py
+++ libcxx/utils/generate_feature_test_macro_components.py
@@ -327,6 +327,13 @@
 "test_suite_guard": "!defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
 "libcxx_guard": "!defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
 "unimplemented": True,
+  }, {
+"name": "__cpp_lib_formatters",
+"values": { "c++2b": 202302 },
+"headers": ["stacktrace", "thread"],
+"test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
+"libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
+"unimplemented": True,
   }, {
 "name": "__cpp_lib_forward_like",
 "values": { "c++2b": 202207 },
Index: libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
===
--- libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
+++ libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
@@ -175,7 +175,8 @@
 // Tests for P1636 Formatters for library types
 //
 // The paper hasn't been voted in so currently all formatters are disabled.
-// TODO validate whether the test is correct after the paper has been accepted.
+// Note the paper has been abandoned, the types are kept since other papers may
+// introduce these formatters.
 template 
 void test_P1636() {
   assert_is_not_formattable, CharT>();
@@ -191,7 +192,7 @@
 assert_is_not_formattable, CharT>();
 #endif
 #ifndef TEST_HAS_NO_THREADS
-  assert_is_not_formattable();
+  assert_is_formattable();
 #endif
   assert_is_not_formattable, CharT>();
 }
Index: libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
===
--- libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
+++ libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
@@ -9,6 +9,9 @@
 // UNSUPPORTED: no-threads
 // UNSUPPORTED: no-localization
 
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
 // 
 
 // class thread::id
@@ -18,16 +21,38 @@
 // operator<<(basic_ostream& out, thread::id id);
 
 #include 
+#include 
 #include 
 #include 
 
+#include "make_string.h"
 #include "test_macros.h"
 
-int main(int, char**)
-{
-std::thread::id id0 = std::this_thread::get_id();
-std::ostringstream os;
-os << id0;
+template 
+static void test() {
+  std::thread::id id0 = std::this_thread::get_id();
+  std::basic_ostringstream os;
+  os << id0;
+
+#if TEST_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+  // C++23 added a formatter 

Re: [clang] e7f55bb - [clang][Interp][NFCI] Call* ops don't modify the PC

2023-04-08 Thread Timm Baeder via cfe-commits

On 08.04.23 14:25, Aaron Ballman wrote:

On Sat, Apr 8, 2023 at 2:50 AM Timm Bäder via cfe-commits
 wrote:



Author: Timm Bäder
Date: 2023-04-08T08:49:22+02:00
New Revision: e7f55bbdb880eb0c096b05d915ee920fe1f2fb98

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

LOG: [clang][Interp][NFCI] Call* ops don't modify the PC


Err, I don't think this is actually NFC given that it's fixing a
crash. Can you add test coverage for the change?

~Aaron


Sure, done: 
https://github.com/llvm/llvm-project/commit/0260ea3a5b1cfa0b0dbb9852742da7480fda620c


- Timm

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


[PATCH] D147774: [4/N][POC][Clang] Define tuple type variant of vsseg2e32

2023-04-08 Thread Yueh-Ting (eop) Chen via Phabricator via cfe-commits
eopXD updated this revision to Diff 511891.
eopXD added a comment.

Minor code change: Separate `defm` of segment load and store under 
`riscv_vector.td`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147774

Files:
  clang/include/clang/Basic/riscv_vector.td
  clang/lib/CodeGen/CGBuiltin.cpp
  
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg2e32_tuple.c

Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg2e32_tuple.c
===
--- /dev/null
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg2e32_tuple.c
@@ -0,0 +1,31 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \
+// RUN:   -target-feature +experimental-zvfh -disable-O0-optnone  \
+// RUN:   -emit-llvm %s -o - | opt -S -passes=mem2reg | \
+// RUN:   FileCheck --check-prefix=CHECK-RV64 %s
+#include 
+
+// CHECK-RV64-LABEL: define dso_local void @test_vsseg2e32_v_tuple_i32m1
+// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]],  [[V_TUPLE_COERCE0:%.*]],  [[V_TUPLE_COERCE1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:[[TMP0:%.*]] = insertvalue { ,  } undef,  [[V_TUPLE_COERCE0]], 0
+// CHECK-RV64-NEXT:[[TMP1:%.*]] = insertvalue { ,  } [[TMP0]],  [[V_TUPLE_COERCE1]], 1
+// CHECK-RV64-NEXT:[[TMP2:%.*]] = extractvalue { ,  } [[TMP1]], 0
+// CHECK-RV64-NEXT:[[TMP3:%.*]] = extractvalue { ,  } [[TMP1]], 1
+// CHECK-RV64-NEXT:call void @llvm.riscv.vsseg2.nxv2i32.i64( [[TMP2]],  [[TMP3]], ptr [[BASE]], i64 [[VL]])
+// CHECK-RV64-NEXT:ret void
+//
+void test_vsseg2e32_v_tuple_i32m1(int32_t *base, vint32m1x2_t v_tuple, size_t vl) {
+  return __riscv_vsseg2e32_v_tuple_i32m1(base, v_tuple, vl);
+}
+
+// CHECK-RV64-LABEL: define dso_local void @test_vsseg2e32_v_i32m1_m
+// CHECK-RV64-SAME: ( [[MASK:%.*]], ptr noundef [[BASE:%.*]],  [[V0:%.*]],  [[V1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:call void @llvm.riscv.vsseg2.mask.nxv2i32.i64( [[V0]],  [[V1]], ptr [[BASE]],  [[MASK]], i64 [[VL]])
+// CHECK-RV64-NEXT:ret void
+//
+void test_vsseg2e32_v_i32m1_m(vbool32_t mask, int32_t *base, vint32m1_t v0, vint32m1_t v1, size_t vl) {
+  return __riscv_vsseg2e32_v_i32m1_m(mask, base, v0, v1, vl);
+}
Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -19602,6 +19602,14 @@
   }
 
   for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
+// Handle aggregate argument, namely RVV tuple types in segment load/store
+if (hasAggregateEvaluationKind(E->getArg(i)->getType())) {
+  LValue L = EmitAggExprToLValue(E->getArg(i));
+  llvm::Value *AggValue = Builder.CreateLoad(L.getAddress(*this));
+  Ops.push_back(AggValue);
+  continue;
+}
+
 // If this is a normal argument, just emit it as a scalar.
 if ((ICEArguments & (1 << i)) == 0) {
   Ops.push_back(EmitScalarExpr(E->getArg(i)));
Index: clang/include/clang/Basic/riscv_vector.td
===
--- clang/include/clang/Basic/riscv_vector.td
+++ clang/include/clang/Basic/riscv_vector.td
@@ -1779,6 +1779,51 @@
 }
   }
 }
+
+multiclass RVVUnitStridedSegStoreTuple {
+  foreach type = ["i"] in {
+defvar eew = !cond(!eq(type, "i") : "32");
+foreach nf = [2] in {
+  let Name = op # nf # "e" # eew # "_v_tuple",
+  OverloadedName = op # nf # "e" # eew # "_tuple",
+  IRName = op # nf,
+  MaskedIRName = op # nf # "_mask",
+  NF = nf,
+  HasMaskedOffOperand = false,
+  ManualCodegen = [{
+{
+  // Masked
+  // Builtin: (mask, ptr, v_tuple, vl)
+  // Intrinsic: (val0, val1, ..., ptr, mask, vl)
+  // Unmasked
+  // Builtin: (ptr, v_tuple, vl)
+  // Intrinsic: (val0, val1, ..., ptr, vl)
+  llvm::Value *MaskOperand = IsMasked ? Ops[0] : nullptr;
+  llvm::Value *PtrOperand = IsMasked ? Ops[1] : Ops[0];
+  llvm::Value *VTupleOperand = IsMasked ? Ops[2] : Ops[1];
+  llvm::Value *VLOperand = IsMasked ? Ops[3] : Ops[2];
+
+  SmallVector Operands;
+  for (unsigned I = 0; I < NF; ++I) {
+llvm::Value *V = Builder.CreateExtractValue(VTupleOperand, {I});
+Operands.push_back(V);
+  }
+  Operands.push_back(PtrOperand);
+  if (MaskOperand)
+Operands.push_back(MaskOperand);
+  Operands.push_back(VLOperand);
+
+  IntrinsicTypes = {Operands[0]->getType(), Operands.back()->getType()};
+  llvm::Function *F = CGM.getIntrinsic(ID, 

[clang] f43adc4 - [clang][Interp] Add missing static_assert message

2023-04-08 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-04-08T15:44:11+02:00
New Revision: f43adc498065fdfa120bd1aeea02c64f7ecea8f9

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

LOG: [clang][Interp] Add missing static_assert message

Added: 


Modified: 
clang/test/AST/Interp/functions.cpp

Removed: 




diff  --git a/clang/test/AST/Interp/functions.cpp 
b/clang/test/AST/Interp/functions.cpp
index 933cc860577e..a8681aae0d58 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -214,10 +214,10 @@ namespace InvalidCall {
 }
   };
   constexpr S s;
-  static_assert(s.a() == 1); // expected-error {{not an integral constant 
expression}} \
- // expected-note {{in call to}} \
- // ref-error {{not an integral constant 
expression}} \
- // ref-note {{in call to}}
+  static_assert(s.a() == 1, ""); // expected-error {{not an integral constant 
expression}} \
+ // expected-note {{in call to}} \
+ // ref-error {{not an integral constant 
expression}} \
+ // ref-note {{in call to}}
 
   /// This used to cause an assertion failure in the new constant interpreter.
   constexpr void func(); // expected-note {{declared here}} \



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


[PATCH] D147175: [clang] Add __is_trivially_equality_comparable

2023-04-08 Thread Nikolas Klauser via Phabricator via cfe-commits
philnik marked an inline comment as done.
philnik added inline comments.



Comment at: libcxx/include/__type_traits/is_equality_comparable.h:46
 template 
-struct __is_trivially_equality_comparable
+struct __libcpp_is_trivially_equality_comparable
 : integral_constant This does not magically use the builtin right? Does the patch miss that parts 
> that use the builtin or is that a followup? If it's a followup I would prefer 
> move the libc++ code changes of this patch to a separate review.
No, it doesn't magically use the builtin. I plan to do that in a follow-up. 
These changes are required though, since clang grabs the name with this patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147175

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


[PATCH] D147845: [clang][Interp] Fix a crash when calling invalid constexpr functions

2023-04-08 Thread Timm Bäder via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG1c818b0a4f92: [clang][Interp] Fix a crash when calling 
invalid constexpr functions (authored by tbaeder).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147845

Files:
  clang/lib/AST/Interp/InterpFrame.cpp
  clang/test/AST/Interp/functions.cpp


Index: clang/test/AST/Interp/functions.cpp
===
--- clang/test/AST/Interp/functions.cpp
+++ clang/test/AST/Interp/functions.cpp
@@ -202,3 +202,20 @@
 constexpr int doit() { return nyd(10); }
 constexpr int nyd(int m) { return m; }
 static_assert(doit() == 10, "");
+
+namespace InvalidCall {
+  struct S {
+constexpr int a() const { // expected-error {{never produces a constant 
expression}} \
+  // ref-error {{never produces a constant 
expression}}
+  return 1 / 0; // expected-note 2{{division by zero}} \
+// expected-warning {{is undefined}} \
+// ref-note 2{{division by zero}} \
+// ref-warning {{is undefined}}
+}
+  };
+  constexpr S s;
+  static_assert(s.a() == 1); // expected-error {{not an integral constant 
expression}} \
+ // expected-note {{in call to}} \
+ // ref-error {{not an integral constant 
expression}} \
+ // ref-note {{in call to}}
+}
Index: clang/lib/AST/Interp/InterpFrame.cpp
===
--- clang/lib/AST/Interp/InterpFrame.cpp
+++ clang/lib/AST/Interp/InterpFrame.cpp
@@ -127,7 +127,8 @@
   }
 
   // Drop the first pointer since we print it unconditionally anyway.
-  Levels.erase(Levels.begin());
+  if (!Levels.empty())
+Levels.erase(Levels.begin());
 
   printDesc(P.getDeclDesc());
   for (const auto  : Levels) {


Index: clang/test/AST/Interp/functions.cpp
===
--- clang/test/AST/Interp/functions.cpp
+++ clang/test/AST/Interp/functions.cpp
@@ -202,3 +202,20 @@
 constexpr int doit() { return nyd(10); }
 constexpr int nyd(int m) { return m; }
 static_assert(doit() == 10, "");
+
+namespace InvalidCall {
+  struct S {
+constexpr int a() const { // expected-error {{never produces a constant expression}} \
+  // ref-error {{never produces a constant expression}}
+  return 1 / 0; // expected-note 2{{division by zero}} \
+// expected-warning {{is undefined}} \
+// ref-note 2{{division by zero}} \
+// ref-warning {{is undefined}}
+}
+  };
+  constexpr S s;
+  static_assert(s.a() == 1); // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to}} \
+ // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to}}
+}
Index: clang/lib/AST/Interp/InterpFrame.cpp
===
--- clang/lib/AST/Interp/InterpFrame.cpp
+++ clang/lib/AST/Interp/InterpFrame.cpp
@@ -127,7 +127,8 @@
   }
 
   // Drop the first pointer since we print it unconditionally anyway.
-  Levels.erase(Levels.begin());
+  if (!Levels.empty())
+Levels.erase(Levels.begin());
 
   printDesc(P.getDeclDesc());
   for (const auto  : Levels) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 0260ea3 - [clang][Interp][NFC] Add test for e7f55bb

2023-04-08 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-04-08T15:28:47+02:00
New Revision: 0260ea3a5b1cfa0b0dbb9852742da7480fda620c

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

LOG: [clang][Interp][NFC] Add test for e7f55bb

Added: 


Modified: 
clang/test/AST/Interp/functions.cpp

Removed: 




diff  --git a/clang/test/AST/Interp/functions.cpp 
b/clang/test/AST/Interp/functions.cpp
index 8b6b1bcd6f5c..933cc860577e 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -218,4 +218,17 @@ namespace InvalidCall {
  // expected-note {{in call to}} \
  // ref-error {{not an integral constant 
expression}} \
  // ref-note {{in call to}}
+
+  /// This used to cause an assertion failure in the new constant interpreter.
+  constexpr void func(); // expected-note {{declared here}} \
+ // ref-note {{declared here}}
+  struct SS {
+constexpr SS() { func(); } // expected-note {{undefined function }} \
+   // ref-note {{undefined function}}
+  };
+  constexpr SS ss; // expected-error {{must be initialized by a constant 
expression}} \
+   // expected-note {{in call to 'SS()'}} \
+   // ref-error {{must be initialized by a constant 
expression}} \
+   // ref-note {{in call to 'SS()'}}
+
 }



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


[clang] 1c818b0 - [clang][Interp] Fix a crash when calling invalid constexpr functions

2023-04-08 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-04-08T15:28:47+02:00
New Revision: 1c818b0a4f92abd6a450841ebca37f3ef5dac0bc

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

LOG: [clang][Interp] Fix a crash when calling invalid constexpr functions

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

Added: 


Modified: 
clang/lib/AST/Interp/InterpFrame.cpp
clang/test/AST/Interp/functions.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpFrame.cpp 
b/clang/lib/AST/Interp/InterpFrame.cpp
index 897d420e91a3a..a8c4aab84ef8d 100644
--- a/clang/lib/AST/Interp/InterpFrame.cpp
+++ b/clang/lib/AST/Interp/InterpFrame.cpp
@@ -127,7 +127,8 @@ void print(llvm::raw_ostream , const Pointer , 
ASTContext ,
   }
 
   // Drop the first pointer since we print it unconditionally anyway.
-  Levels.erase(Levels.begin());
+  if (!Levels.empty())
+Levels.erase(Levels.begin());
 
   printDesc(P.getDeclDesc());
   for (const auto  : Levels) {

diff  --git a/clang/test/AST/Interp/functions.cpp 
b/clang/test/AST/Interp/functions.cpp
index 06edcdeffa705..8b6b1bcd6f5c3 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -202,3 +202,20 @@ constexpr int nyd(int m);
 constexpr int doit() { return nyd(10); }
 constexpr int nyd(int m) { return m; }
 static_assert(doit() == 10, "");
+
+namespace InvalidCall {
+  struct S {
+constexpr int a() const { // expected-error {{never produces a constant 
expression}} \
+  // ref-error {{never produces a constant 
expression}}
+  return 1 / 0; // expected-note 2{{division by zero}} \
+// expected-warning {{is undefined}} \
+// ref-note 2{{division by zero}} \
+// ref-warning {{is undefined}}
+}
+  };
+  constexpr S s;
+  static_assert(s.a() == 1); // expected-error {{not an integral constant 
expression}} \
+ // expected-note {{in call to}} \
+ // ref-error {{not an integral constant 
expression}} \
+ // ref-note {{in call to}}
+}



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


[PATCH] D147175: [clang] Add __is_trivially_equality_comparable

2023-04-08 Thread Mark de Wever via Phabricator via cfe-commits
Mordante added a comment.

I mainly glossed over the patch and didn't do a real review.




Comment at: clang/lib/AST/ASTContext.cpp:2672
+const RecordDecl *RD,
+bool CheckIfTriviallyCOpyable) 
{
   assert(RD->isUnion() && "Must be union type");





Comment at: libcxx/include/__type_traits/is_equality_comparable.h:46
 template 
-struct __is_trivially_equality_comparable
+struct __libcpp_is_trivially_equality_comparable
 : integral_constanthttps://reviews.llvm.org/D147175/new/

https://reviews.llvm.org/D147175

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


[PATCH] D146986: Downgrade reserved module identifier error into a warning

2023-04-08 Thread Mark de Wever via Phabricator via cfe-commits
Mordante added a comment.

Sorry I was not available earlier. Thanks for working on this. LGTM but one 
remark.




Comment at: clang/docs/ReleaseNotes.rst:92
+  `_ and allows easier
+  building of precompiled modules. This diagnostic may be strengthened into an
+  error again in the future once there is a less fragile way to mark a module

Note this is about the standard modules, which are not precompiled per se.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146986

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


[PATCH] D147845: [clang][Interp] Fix a crash when calling invalid constexpr functions

2023-04-08 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM




Comment at: clang/test/AST/Interp/functions.cpp:210-212
+  return 1 / 0; // expected-note 2{{division by zero}} \
+// expected-warning {{is undefined}} \
+// ref-note 2{{division by zero}} \

It'd be nice if we didn't issue duplicate notes in this case, but given that 
the behavior matches the reference implementation, it's reasonable enough.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147845

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


[PATCH] D147534: [clang][Interp] Make sure we have a variable scope for initializers

2023-04-08 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/test/AST/Interp/records.cpp:315
+  auto T = Test(Arr, Pos);
+  // End of scope, should destroy Test.
+}

tbaeder wrote:
> aaron.ballman wrote:
> > Would it make sense to give `Test` a constexpr destructor so that we can 
> > validate it's being called? e.g. https://godbolt.org/z/fhE7xzE4e
> That just tests regular destructors, doesn't it? That's already covered by 
> other tests.
Yeah, that's fair I suppose. :-)


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

https://reviews.llvm.org/D147534

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


Re: [clang] e7f55bb - [clang][Interp][NFCI] Call* ops don't modify the PC

2023-04-08 Thread Aaron Ballman via cfe-commits
On Sat, Apr 8, 2023 at 2:50 AM Timm Bäder via cfe-commits
 wrote:
>
>
> Author: Timm Bäder
> Date: 2023-04-08T08:49:22+02:00
> New Revision: e7f55bbdb880eb0c096b05d915ee920fe1f2fb98
>
> URL: 
> https://github.com/llvm/llvm-project/commit/e7f55bbdb880eb0c096b05d915ee920fe1f2fb98
> DIFF: 
> https://github.com/llvm/llvm-project/commit/e7f55bbdb880eb0c096b05d915ee920fe1f2fb98.diff
>
> LOG: [clang][Interp][NFCI] Call* ops don't modify the PC

Err, I don't think this is actually NFC given that it's fixing a
crash. Can you add test coverage for the change?

~Aaron

>
> This caused the reported errors from the Call*() handlers to report the
> wrong source location.
>
> Fixes: https://github.com/llvm/llvm-project/issues/62002
>
> Added:
>
>
> Modified:
> clang/lib/AST/Interp/Interp.h
> clang/lib/AST/Interp/Opcodes.td
>
> Removed:
>
>
>
> 
> diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
> index afc5f24baf73..1eda38e9fa5b 100644
> --- a/clang/lib/AST/Interp/Interp.h
> +++ b/clang/lib/AST/Interp/Interp.h
> @@ -1486,28 +1486,29 @@ inline bool ArrayElemPtrPop(InterpState , CodePtr 
> OpPC) {
>return NarrowPtr(S, OpPC);
>  }
>
> -inline bool CheckGlobalCtor(InterpState , CodePtr ) {
> +inline bool CheckGlobalCtor(InterpState , CodePtr OpPC) {
>const Pointer  = S.Stk.peek();
> -  return CheckCtorCall(S, PC, Obj);
> +  return CheckCtorCall(S, OpPC, Obj);
>  }
>
> -inline bool Call(InterpState , CodePtr , const Function *Func) {
> +inline bool Call(InterpState , CodePtr OpPC, const Function *Func) {
>if (Func->hasThisPointer()) {
>  size_t ThisOffset =
>  Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0);
> +
>  const Pointer  = S.Stk.peek(ThisOffset);
>
> -if (!CheckInvoke(S, PC, ThisPtr))
> +if (!CheckInvoke(S, OpPC, ThisPtr))
>return false;
>
>  if (S.checkingPotentialConstantExpression())
>return false;
>}
>
> -  if (!CheckCallable(S, PC, Func))
> +  if (!CheckCallable(S, OpPC, Func))
>  return false;
>
> -  auto NewFrame = std::make_unique(S, Func, PC);
> +  auto NewFrame = std::make_unique(S, Func, OpPC);
>InterpFrame *FrameBefore = S.Current;
>S.Current = NewFrame.get();
>
> @@ -1541,14 +1542,14 @@ inline bool CallBI(InterpState , CodePtr , const 
> Function *Func) {
>return false;
>  }
>
> -inline bool CallPtr(InterpState , CodePtr ) {
> +inline bool CallPtr(InterpState , CodePtr OpPC) {
>const FunctionPointer  = S.Stk.pop();
>
>const Function *F = FuncPtr.getFunction();
>if (!F || !F->isConstexpr())
>  return false;
>
> -  return Call(S, PC, F);
> +  return Call(S, OpPC, F);
>  }
>
>  inline bool GetFnPtr(InterpState , CodePtr , const Function *Func) {
>
> diff  --git a/clang/lib/AST/Interp/Opcodes.td 
> b/clang/lib/AST/Interp/Opcodes.td
> index f3662dcd6f43..ed0774a78833 100644
> --- a/clang/lib/AST/Interp/Opcodes.td
> +++ b/clang/lib/AST/Interp/Opcodes.td
> @@ -179,19 +179,16 @@ def NoRet : Opcode {}
>  def Call : Opcode {
>let Args = [ArgFunction];
>let Types = [];
> -  let ChangesPC = 1;
>  }
>
>  def CallBI : Opcode {
>let Args = [ArgFunction];
>let Types = [];
> -  let ChangesPC = 1;
>  }
>
>  def CallPtr : Opcode {
>let Args = [];
>let Types = [];
> -  let ChangesPC = 1;
>  }
>
>  
> //===--===//
>
>
>
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147848: [clang] Add test for CWG2370

2023-04-08 Thread Vlad Serebrennikov via Phabricator via cfe-commits
Endill created this revision.
Endill added a reviewer: clang-language-wg.
Herald added a project: All.
Endill requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

P1787 : CWG2370 is resolved by performing a search in 
(only) the immediate scope of any friend, per the CWG opinion from San Diego 
.
Wording: In a friend declaration declarator whose declarator-id is a 
qualified-id whose lookup context is a class or namespace S, lookup for an 
unqualified name that appears after the declarator-id performs a search in the 
scope associated with S. If that lookup finds nothing, it undergoes unqualified 
name lookup. ([basic.lookup.unqual]/6).

Clarification for P1787  description: when 
applied to the test in this patch, "immediate scope" refers to `N`, and 
"(only)" refers to the fact that `type` is not searched in parent scope of `N`. 
See example after the wording if additional clarification is needed. The most 
relevant line there is `friend void A::f(F);  // OK`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147848

Files:
  clang/test/CXX/drs/dr23xx.cpp
  clang/www/cxx_dr_status.html


Index: clang/www/cxx_dr_status.html
===
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -14027,7 +14027,7 @@
 https://wg21.link/cwg2370;>2370
 CD6
 friend declarations of namespace-scope functions
-Unknown
+No
   
   
 https://wg21.link/cwg2371;>2371
Index: clang/test/CXX/drs/dr23xx.cpp
===
--- clang/test/CXX/drs/dr23xx.cpp
+++ clang/test/CXX/drs/dr23xx.cpp
@@ -2,7 +2,9 @@
 // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions 
-pedantic-errors 2>&1 | FileCheck %s
 // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions 
-pedantic-errors 2>&1 | FileCheck %s
 // RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions 
-pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions 
-pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions 
-pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++2b %s -verify -fexceptions -fcxx-exceptions 
-pedantic-errors 2>&1 | FileCheck %s
+
 
 #if __cplusplus >= 201103L
 namespace dr2338 { // dr2338: 12
@@ -169,6 +171,20 @@
 } //namespace dr2303
 #endif
 
+namespace dr2370 { // dr2370: no
+namespace N {
+typedef int type;
+void g(type);
+void h(type);
+} // namespace N
+class C {
+  typedef N::type N_type;
+  // FIXME: `type` should be searched for in N
+  // friend void N::g(type);
+  friend void N::h(N_type);
+};
+} // namespace dr2370
+
 // dr2385: na
 
 namespace dr2394 { // dr2394: 15


Index: clang/www/cxx_dr_status.html
===
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -14027,7 +14027,7 @@
 https://wg21.link/cwg2370;>2370
 CD6
 friend declarations of namespace-scope functions
-Unknown
+No
   
   
 https://wg21.link/cwg2371;>2371
Index: clang/test/CXX/drs/dr23xx.cpp
===
--- clang/test/CXX/drs/dr23xx.cpp
+++ clang/test/CXX/drs/dr23xx.cpp
@@ -2,7 +2,9 @@
 // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
 // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
 // RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++2b %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+
 
 #if __cplusplus >= 201103L
 namespace dr2338 { // dr2338: 12
@@ -169,6 +171,20 @@
 } //namespace dr2303
 #endif
 
+namespace dr2370 { // dr2370: no
+namespace N {
+typedef int type;
+void g(type);
+void h(type);
+} // namespace N
+class C {
+  typedef N::type N_type;
+  // FIXME: `type` should be searched for in N
+  // friend void N::g(type);
+  friend void N::h(N_type);
+};
+} // namespace dr2370
+
 // dr2385: na
 
 namespace dr2394 { // dr2394: 15
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147847: [clangd] Hover: Add CalleeArgInfo for constructor expressions

2023-04-08 Thread Tom Praschan via Phabricator via cfe-commits
tom-anders added a comment.

(Note that this diff is stacked on D147846 )


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147847

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


[PATCH] D147847: [clangd] Hover: Add CalleeArgInfo for constructor expressions

2023-04-08 Thread Tom Praschan via Phabricator via cfe-commits
tom-anders added inline comments.



Comment at: clang-tools-extra/clangd/Hover.cpp:986
+  const FunctionDecl *FD = nullptr;
+  llvm::SmallVector Args;
+

Unfortunately, while CallExpr and CXXConstructExpr basically have the same API 
for getting Args, they're not related by a common base class.

Is there a more elegant solution than temporarily storing the Args in a 
SmallVector here?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147847

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


[PATCH] D147847: [clangd] Hover: Add CalleeArgInfo for constructor expressions

2023-04-08 Thread Tom Praschan via Phabricator via cfe-commits
tom-anders created this revision.
tom-anders added reviewers: nridge, sammccall.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
tom-anders requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147847

Files:
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp


Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -956,6 +956,29 @@
 HI.CalleeArgInfo->Type = "const float &";
 HI.CallPassType = HoverInfo::PassType{PassMode::Value, true};
   }},
+  {
+  R"cpp(
+  struct Foo {
+explicit Foo(const float& arg) {}
+  };
+  int main() {
+int a = 0;
+Foo foo([[^a]]);
+  }
+  )cpp",
+  [](HoverInfo ) {
+HI.Name = "a";
+HI.Kind = index::SymbolKind::Variable;
+HI.NamespaceScope = "";
+HI.Definition = "int a = 0";
+HI.LocalScope = "main::";
+HI.Value = "0";
+HI.Type = "int";
+HI.CalleeArgInfo.emplace();
+HI.CalleeArgInfo->Name = "arg";
+HI.CalleeArgInfo->Type = "const float &";
+HI.CallPassType = HoverInfo::PassType{PassMode::Value, true};
+  }},
   {// Literal passed to function call
R"cpp(
   void fun(int arg_a, const int _b) {};
@@ -1342,6 +1365,7 @@
   CustomClass(const Base ) {}
   CustomClass(int ) {}
   CustomClass(float x) {}
+  CustomClass(int x, int y) {}
 };
 
 void int_by_ref(int ) {}
@@ -1388,6 +1412,11 @@
   {"base_by_ref([[^derived]]);", PassMode::Ref, false},
   {"base_by_const_ref([[^derived]]);", PassMode::ConstRef, false},
   {"base_by_value([[^derived]]);", PassMode::Value, false},
+  // Custom class constructor tests
+  {"CustomClass c1([[^base]]);", PassMode::ConstRef, false},
+  {"auto c2 = new CustomClass([[^base]]);", PassMode::ConstRef, false},
+  {"CustomClass c3([[^int_x]]);", PassMode::Ref, false},
+  {"CustomClass c3(int_x, [[^int_x]]);", PassMode::Value, false},
   // Converted tests
   {"float_by_value([[^int_x]]);", PassMode::Value, true},
   {"float_by_value([[^int_ref]]);", PassMode::Value, true},
Index: clang-tools-extra/clangd/Hover.cpp
===
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -981,10 +981,21 @@
   const auto  = N->outerImplicit();
   if (!OuterNode.Parent)
 return;
-  const auto *CE = OuterNode.Parent->ASTNode.get();
-  if (!CE)
+
+  const FunctionDecl *FD = nullptr;
+  llvm::SmallVector Args;
+
+  if (const auto *CE = OuterNode.Parent->ASTNode.get()) {
+FD = CE->getDirectCallee();
+Args = {CE->arg_begin(), CE->arg_end()};
+  } else if (const auto *CE =
+ OuterNode.Parent->ASTNode.get()) {
+FD = CE->getConstructor();
+Args = {CE->arg_begin(), CE->arg_end()};
+  }
+  if (!FD)
 return;
-  const FunctionDecl *FD = CE->getDirectCallee();
+
   // For non-function-call-like operatators (e.g. operator+, operator<<) it's
   // not immediattely obvious what the "passed as" would refer to and, given
   // fixed function signature, the value would be very low anyway, so we choose
@@ -999,8 +1010,8 @@
   auto Parameters = resolveForwardingParameters(FD);
 
   // Find argument index for N.
-  for (unsigned I = 0; I < CE->getNumArgs() && I < Parameters.size(); ++I) {
-if (CE->getArg(I) != OuterNode.ASTNode.get())
+  for (unsigned I = 0; I < Args.size() && I < Parameters.size(); ++I) {
+if (Args[I] != OuterNode.ASTNode.get())
   continue;
 
 // Extract matching argument from function declaration.


Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -956,6 +956,29 @@
 HI.CalleeArgInfo->Type = "const float &";
 HI.CallPassType = HoverInfo::PassType{PassMode::Value, true};
   }},
+  {
+  R"cpp(
+  struct Foo {
+explicit Foo(const float& arg) {}
+  };
+  int main() {
+int a = 0;
+Foo foo([[^a]]);
+  }
+  )cpp",
+  [](HoverInfo ) {
+HI.Name = "a";
+HI.Kind = index::SymbolKind::Variable;
+HI.NamespaceScope = "";
+HI.Definition = "int a = 0";
+HI.LocalScope = "main::";
+HI.Value = "0";
+HI.Type = "int";
+

[PATCH] D144331: [libc++][format] Implements formatter thread::id.

2023-04-08 Thread Mark de Wever via Phabricator via cfe-commits
Mordante updated this revision to Diff 511875.
Mordante added a comment.

CI fixes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144331

Files:
  libcxx/docs/FeatureTestMacroTable.rst
  libcxx/docs/ReleaseNotes.rst
  libcxx/docs/Status/Cxx2b.rst
  libcxx/docs/Status/Cxx2bPapers.csv
  libcxx/docs/Status/FormatPaper.csv
  libcxx/include/__format/parser_std_format_spec.h
  libcxx/include/__threading_support
  libcxx/include/thread
  libcxx/include/version
  libcxx/test/libcxx/transitive_includes/cxx03.csv
  libcxx/test/libcxx/transitive_includes/cxx11.csv
  libcxx/test/libcxx/transitive_includes/cxx14.csv
  libcxx/test/libcxx/transitive_includes/cxx17.csv
  libcxx/test/libcxx/transitive_includes/cxx20.csv
  libcxx/test/libcxx/transitive_includes/cxx2b.csv
  
libcxx/test/std/language.support/support.limits/support.limits.general/thread.version.compile.pass.cpp
  
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.format.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.tests.h
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.vformat.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/parse.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
  
libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
  libcxx/utils/generate_feature_test_macro_components.py

Index: libcxx/utils/generate_feature_test_macro_components.py
===
--- libcxx/utils/generate_feature_test_macro_components.py
+++ libcxx/utils/generate_feature_test_macro_components.py
@@ -327,6 +327,13 @@
 "test_suite_guard": "!defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
 "libcxx_guard": "!defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
 "unimplemented": True,
+  }, {
+"name": "__cpp_lib_formatters",
+"values": { "c++2b": 202302 },
+"headers": ["stacktrace", "thread"],
+"test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
+"libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
+"unimplemented": True,
   }, {
 "name": "__cpp_lib_forward_like",
 "values": { "c++2b": 202207 },
Index: libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
===
--- libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
+++ libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
@@ -175,7 +175,8 @@
 // Tests for P1636 Formatters for library types
 //
 // The paper hasn't been voted in so currently all formatters are disabled.
-// TODO validate whether the test is correct after the paper has been accepted.
+// Note the paper has been abandoned, the types are kept since other papers may
+// introduce these formatters.
 template 
 void test_P1636() {
   assert_is_not_formattable, CharT>();
@@ -191,7 +192,7 @@
 assert_is_not_formattable, CharT>();
 #endif
 #ifndef TEST_HAS_NO_THREADS
-  assert_is_not_formattable();
+  assert_is_formattable();
 #endif
   assert_is_not_formattable, CharT>();
 }
Index: libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
===
--- libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
+++ libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
@@ -9,6 +9,9 @@
 // UNSUPPORTED: no-threads
 // UNSUPPORTED: no-localization
 
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
 // 
 
 // class thread::id
@@ -18,16 +21,38 @@
 // operator<<(basic_ostream& out, thread::id id);
 
 #include 
+#include 
 #include 
 #include 
 
+#include "make_string.h"
 #include "test_macros.h"
 
-int main(int, char**)
-{
-std::thread::id id0 = std::this_thread::get_id();
-std::ostringstream os;
-os << id0;
+template 
+static void test() {
+  std::thread::id id0 = std::this_thread::get_id();
+  std::basic_ostringstream os;
+  os << id0;
+
+#if TEST_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+  // C++23 added a formatter specialization for thread::id.
+  // This changed the requirement of ostream to have a
+  // [thread.thread.id]/2
+  //   The text representation for the 

[PATCH] D146904: [clang-tidy] Fix extern fixes in readability-redundant-declaration

2023-04-08 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp added a comment.

Looks good, thanks for the fix! Do we think it's worth documenting in the 
Release Notes?




Comment at: 
clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp:86
+  Result.Nodes.getNodeAs("extern");
+  Extern && !Extern->hasBraces())
+BeginLoc = Extern->getExternLoc();

This can be removed, leaving it as:

```
if (const auto *Extern = ... && !Extern->hasBraces())
```



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-declaration.cpp:126
+extern "C" int externX;
+int dumyBegin;extern "C" int externX;int dummyEnd;
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: redundant 'externX' declaration 
[readability-redundant-declaration]

Typo: dummy

I don't quite see why these are needed to test the example in PR42068?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146904

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


[PATCH] D147834: [clang][driver] Pass `-femulated-tls` through to the linker in LTO mode

2023-04-08 Thread Vitaly Cheptsov via Phabricator via cfe-commits
vit9696 accepted this revision.
vit9696 added a comment.
This revision is now accepted and ready to land.

Looks good to me, thank you!




Comment at: clang/test/Driver/emulated-tls.cpp:57
+// LTO related checks
+//LTO_NOEMUTLS: plugin-opt=-emulated-tls=0
+//LTO_NOEMUTLS-NOT: plugin-opt=-emulated-tls=1

Maybe add a space before LTO here?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147834

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


[PATCH] D146520: [clang-tidy] Fix checks filter with warnings-as-errors

2023-04-08 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp accepted this revision.
carlosgalvezp added a comment.

Having another look and reading your comments I got a better understanding of 
the situation:

- YAML output did not have correct warnings as errors.
- Thus a fix was introduced in ClangTidyDiagnosticConsumer, however this was a 
too broad place to put the fix, breaking diagnostics output by command-line.
- Instead, the fix should have been put in a narrower scope, in the part of the 
code that deals with YAML output.
- This patch does exactly that.

So this patch is not really altering the original diagnostic behavior. In that 
sense I'm ok with it! I suppose it would have been clearer from a review 
perspective if first a revert was made and then re-landed with the correct 
code, but it's probably too much annoyance for such a small change.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146520

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


[PATCH] D147846: [clangd] Hover: resolve forwarding parameters for CalleeArgInfo

2023-04-08 Thread Tom Praschan via Phabricator via cfe-commits
tom-anders created this revision.
tom-anders added reviewers: nridge, upsj.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
tom-anders requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

This uses the logic added in D124690 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147846

Files:
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp


Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -906,6 +906,35 @@
  HI.CalleeArgInfo->Type = "int &";
  HI.CallPassType = HoverInfo::PassType{PassMode::Ref, false};
}},
+  {// make_unique-like function call
+   R"cpp(
+  struct Foo {
+explicit Foo(int arg_a) {}
+  };
+  template
+  T make(Args&&... args)
+  {
+  return T(args...);
+  }
+
+  void code() {
+int a = 1;
+auto foo = make([[^a]]);
+  }
+  )cpp",
+   [](HoverInfo ) {
+ HI.Name = "a";
+ HI.Kind = index::SymbolKind::Variable;
+ HI.NamespaceScope = "";
+ HI.Definition = "int a = 1";
+ HI.LocalScope = "code::";
+ HI.Value = "1";
+ HI.Type = "int";
+ HI.CalleeArgInfo.emplace();
+ HI.CalleeArgInfo->Name = "arg_a";
+ HI.CalleeArgInfo->Type = "int";
+ HI.CallPassType = HoverInfo::PassType{PassMode::Value, false};
+   }},
   {
   R"cpp(
   void foobar(const float );
Index: clang-tools-extra/clangd/Hover.cpp
===
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -996,13 +996,15 @@
 
   HoverInfo::PassType PassType;
 
+  auto Parameters = resolveForwardingParameters(FD);
+
   // Find argument index for N.
-  for (unsigned I = 0; I < CE->getNumArgs() && I < FD->getNumParams(); ++I) {
+  for (unsigned I = 0; I < CE->getNumArgs() && I < Parameters.size(); ++I) {
 if (CE->getArg(I) != OuterNode.ASTNode.get())
   continue;
 
 // Extract matching argument from function declaration.
-if (const ParmVarDecl *PVD = FD->getParamDecl(I)) {
+if (const ParmVarDecl *PVD = Parameters[I]) {
   HI.CalleeArgInfo.emplace(toHoverInfoParam(PVD, PP));
   if (N == )
 PassType.PassBy = getPassMode(PVD->getType());


Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -906,6 +906,35 @@
  HI.CalleeArgInfo->Type = "int &";
  HI.CallPassType = HoverInfo::PassType{PassMode::Ref, false};
}},
+  {// make_unique-like function call
+   R"cpp(
+  struct Foo {
+explicit Foo(int arg_a) {}
+  };
+  template
+  T make(Args&&... args)
+  {
+  return T(args...);
+  }
+
+  void code() {
+int a = 1;
+auto foo = make([[^a]]);
+  }
+  )cpp",
+   [](HoverInfo ) {
+ HI.Name = "a";
+ HI.Kind = index::SymbolKind::Variable;
+ HI.NamespaceScope = "";
+ HI.Definition = "int a = 1";
+ HI.LocalScope = "code::";
+ HI.Value = "1";
+ HI.Type = "int";
+ HI.CalleeArgInfo.emplace();
+ HI.CalleeArgInfo->Name = "arg_a";
+ HI.CalleeArgInfo->Type = "int";
+ HI.CallPassType = HoverInfo::PassType{PassMode::Value, false};
+   }},
   {
   R"cpp(
   void foobar(const float );
Index: clang-tools-extra/clangd/Hover.cpp
===
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -996,13 +996,15 @@
 
   HoverInfo::PassType PassType;
 
+  auto Parameters = resolveForwardingParameters(FD);
+
   // Find argument index for N.
-  for (unsigned I = 0; I < CE->getNumArgs() && I < FD->getNumParams(); ++I) {
+  for (unsigned I = 0; I < CE->getNumArgs() && I < Parameters.size(); ++I) {
 if (CE->getArg(I) != OuterNode.ASTNode.get())
   continue;
 
 // Extract matching argument from function declaration.
-if (const ParmVarDecl *PVD = FD->getParamDecl(I)) {
+if (const ParmVarDecl *PVD = Parameters[I]) {
   HI.CalleeArgInfo.emplace(toHoverInfoParam(PVD, PP));
   if (N == )
 PassType.PassBy = getPassMode(PVD->getType());
___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[PATCH] D146809: [WIP][clang-repl] Implement Value pretty printing

2023-04-08 Thread Jun Zhang via Phabricator via cfe-commits
junaire updated this revision to Diff 511871.
junaire added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146809

Files:
  clang/include/clang/Interpreter/Interpreter.h
  clang/lib/Headers/CMakeLists.txt
  clang/lib/Headers/__clang_interpreter_runtime_printvalue.h
  clang/lib/Interpreter/CMakeLists.txt
  clang/lib/Interpreter/IncrementalExecutor.cpp
  clang/lib/Interpreter/IncrementalExecutor.h
  clang/lib/Interpreter/IncrementalParser.h
  clang/lib/Interpreter/Interpreter.cpp
  clang/lib/Interpreter/InterpreterUtils.cpp
  clang/lib/Interpreter/InterpreterUtils.h
  clang/lib/Interpreter/Value.cpp
  clang/lib/Interpreter/ValuePrinter.cpp
  clang/test/Interpreter/pretty-print.cpp

Index: clang/test/Interpreter/pretty-print.cpp
===
--- /dev/null
+++ clang/test/Interpreter/pretty-print.cpp
@@ -0,0 +1,51 @@
+// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \
+// RUN:'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s
+// UNSUPPORTED: system-aix
+// CHECK-DRIVER: i = 10
+// RUN: cat %s | clang-repl | FileCheck %s
+char c = 'a';
+c
+// CHECK: (char) 'a'
+
+int x = 42;
+x
+// CHECK-NEXT: (int) 42
+
+x - 2
+// CHECK-NEXT: (int) 40
+
+float f = 4.2f;
+f
+// CHECK-NEXT: (float) 4.2f
+
+double d = 4.21;
+d
+// CHECK-NEXT: (double) 4.210
+
+struct S{};
+S s;
+s
+// CHECK-NEXT: (S &) [[Addr:@0x.*]]
+
+S{}
+// CHECK-NEXT: (S) [[Addr:@0x.*]]
+
+struct SS { int* p; SS() { p = new int(42); } ~SS() { delete p; } };
+SS{}
+// CHECK-NEXT: (SS) [[Addr:@0x.*]]
+SS ss;
+ss
+// CHECK-NEXT: (SS &) [[Addr:@0x.*]]
+
+int arr[3] = {1,2,3};
+arr
+// CHECK-NEXT: (int[3]) { 1, 2, 3 }
+
+#include 
+
+auto p1 = std::make_shared(42);
+p1
+// CHECK-NEXT: (shared_ptr &) std::shared_ptr -> [[Addr:@0x.*]]
+
+%quit
+
Index: clang/lib/Interpreter/ValuePrinter.cpp
===
--- /dev/null
+++ clang/lib/Interpreter/ValuePrinter.cpp
@@ -0,0 +1,507 @@
+#include "InterpreterUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Type.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/Value.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+#include 
+
+using namespace clang;
+
+namespace rep_runtime_internal {
+REPL_EXTERNAL_VISIBILITY
+extern const char *const kEmptyCollection = "{}";
+} // namespace rep_runtime_internal
+
+static std::string PrintDeclType(const QualType , NamedDecl *D) {
+  std::string Str;
+  llvm::raw_string_ostream SS(Str);
+  if (QT.hasQualifiers())
+SS << QT.getQualifiers().getAsString() << " ";
+  SS << D->getQualifiedNameAsString();
+  return Str;
+}
+
+static std::string PrintQualType(ASTContext , QualType QT) {
+  std::string Str;
+  llvm::raw_string_ostream SS(Str);
+  PrintingPolicy Policy(Ctx.getPrintingPolicy());
+  // Print the Allocator in STL containers, for instance.
+  Policy.SuppressDefaultTemplateArgs = false;
+  Policy.SuppressUnwrittenScope = true;
+  // Print 'a >' rather than 'a>'.
+  Policy.SplitTemplateClosers = true;
+
+  struct LocalPrintingPolicyRAII {
+ASTContext 
+PrintingPolicy Policy;
+
+LocalPrintingPolicyRAII(ASTContext , PrintingPolicy )
+: Context(Ctx), Policy(Ctx.getPrintingPolicy()) {
+  Context.setPrintingPolicy(PP);
+}
+~LocalPrintingPolicyRAII() { Context.setPrintingPolicy(Policy); }
+  } X(Ctx, Policy);
+
+  const QualType NonRefTy = QT.getNonReferenceType();
+
+  if (const auto *TTy = llvm::dyn_cast(NonRefTy))
+SS << PrintDeclType(NonRefTy, TTy->getDecl());
+  else if (const auto *TRy = dyn_cast(NonRefTy))
+SS << PrintDeclType(NonRefTy, TRy->getDecl());
+  else {
+const QualType Canon = NonRefTy.getCanonicalType();
+if (Canon->isBuiltinType() && !NonRefTy->isFunctionPointerType() &&
+!NonRefTy->isMemberPointerType()) {
+  SS << Canon.getAsString(Ctx.getPrintingPolicy());
+} else if (const auto *TDTy = dyn_cast(NonRefTy)) {
+  // FIXME: TemplateSpecializationType & SubstTemplateTypeParmType checks
+  // are predominately to get STL containers to print nicer and might be
+  // better handled in GetFullyQualifiedName.
+  //
+  // std::vector::iterator is a TemplateSpecializationType
+  // std::vector::value_type is a SubstTemplateTypeParmType
+  //
+  QualType SSDesugar = TDTy->getLocallyUnqualifiedSingleStepDesugaredType();
+  if (llvm::isa(SSDesugar))
+SS << GetFullTypeName(Ctx, Canon);
+  else if (llvm::isa(SSDesugar))
+SS << GetFullTypeName(Ctx, NonRefTy);
+  else
+SS << PrintDeclType(NonRefTy, TDTy->getDecl());

[PATCH] D141215: [clang-repl] Introduce Value to capture expression results

2023-04-08 Thread Jun Zhang via Phabricator via cfe-commits
junaire updated this revision to Diff 511870.
junaire added a comment.

Remove some unnecessary code.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141215

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Interpreter/Interpreter.h
  clang/include/clang/Interpreter/Value.h
  clang/include/clang/Parse/Parser.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Frontend/PrintPreprocessedOutput.cpp
  clang/lib/Interpreter/CMakeLists.txt
  clang/lib/Interpreter/IncrementalParser.cpp
  clang/lib/Interpreter/IncrementalParser.h
  clang/lib/Interpreter/Interpreter.cpp
  clang/lib/Interpreter/InterpreterUtils.cpp
  clang/lib/Interpreter/InterpreterUtils.h
  clang/lib/Interpreter/Value.cpp
  clang/lib/Lex/PPLexerChange.cpp
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/Parser.cpp
  clang/tools/clang-repl/CMakeLists.txt
  clang/unittests/Interpreter/CMakeLists.txt
  clang/unittests/Interpreter/InterpreterTest.cpp

Index: clang/unittests/Interpreter/InterpreterTest.cpp
===
--- clang/unittests/Interpreter/InterpreterTest.cpp
+++ clang/unittests/Interpreter/InterpreterTest.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/Mangle.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Interpreter/Value.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Sema.h"
 
@@ -33,6 +34,10 @@
 #define CLANG_INTERPRETER_NO_SUPPORT_EXEC
 #endif
 
+int Global = 42;
+int getGlobal() { return Global; }
+void setGlobal(int val) { Global = val; }
+
 namespace {
 using Args = std::vector;
 static std::unique_ptr
@@ -276,8 +281,7 @@
   std::vector Args = {"-fno-delayed-template-parsing"};
   std::unique_ptr Interp = createInterpreter(Args);
 
-  llvm::cantFail(Interp->Parse("void* operator new(__SIZE_TYPE__, void* __p);"
-   "extern \"C\" int printf(const char*,...);"
+  llvm::cantFail(Interp->Parse("extern \"C\" int printf(const char*,...);"
"class A {};"
"struct B {"
"  template"
@@ -314,4 +318,54 @@
   free(NewA);
 }
 
+TEST(InterpreterTest, Value) {
+  std::unique_ptr Interp = createInterpreter();
+
+  Value V1;
+  llvm::cantFail(Interp->ParseAndExecute("int x = 42;"));
+  llvm::cantFail(Interp->ParseAndExecute("x", ));
+  EXPECT_TRUE(V1.isValid());
+  EXPECT_EQ(V1.getInt(), 42);
+  EXPECT_TRUE(V1.getType()->isIntegerType());
+  EXPECT_EQ(V1.getKind(), Value::K_Int);
+  EXPECT_FALSE(V1.isManuallyAlloc());
+  EXPECT_FALSE(V1.isPointerOrObjectType());
+
+  Value V2;
+  llvm::cantFail(Interp->ParseAndExecute("double y = 3.14;"));
+  llvm::cantFail(Interp->ParseAndExecute("y", ));
+  EXPECT_TRUE(V2.isValid());
+  EXPECT_EQ(V2.getDouble(), 3.14);
+  EXPECT_TRUE(V2.getType()->isFloatingType());
+  EXPECT_EQ(V2.getKind(), Value::K_Double);
+  EXPECT_FALSE(V2.isManuallyAlloc());
+  EXPECT_FALSE(V2.isPointerOrObjectType());
+
+  Value V3;
+  llvm::cantFail(Interp->ParseAndExecute("struct S { int* p; S() { p = new int(42); } ~S() { delete p; }};"));
+  llvm::cantFail(Interp->ParseAndExecute("S{}", ));
+  EXPECT_TRUE(V3.isValid());
+  EXPECT_TRUE(V3.getType()->isRecordType());
+  EXPECT_EQ(V3.getKind(), Value::K_PtrOrObj);
+  EXPECT_TRUE(V3.isManuallyAlloc());
+  EXPECT_TRUE(V3.isPointerOrObjectType());
+
+  Value V4;
+  llvm::cantFail(Interp->ParseAndExecute("int getGlobal();"));
+  llvm::cantFail(Interp->ParseAndExecute("void setGlobal(int);"));
+  llvm::cantFail(Interp->ParseAndExecute("getGlobal()", ));
+  EXPECT_EQ(V4.getInt(), 42);
+  EXPECT_TRUE(V4.getType()->isIntegerType());
+
+  Value V5;
+  // Change the global from the compiled code.
+  setGlobal(43);
+  llvm::cantFail(Interp->ParseAndExecute("getGlobal()", ));
+  EXPECT_EQ(V5.getInt(), 43);
+  EXPECT_TRUE(V5.getType()->isIntegerType());
+
+  // Change the global from the interpreted code.
+  llvm::cantFail(Interp->ParseAndExecute("setGlobal(44);"));
+  EXPECT_EQ(getGlobal(), 44);
+}
 } // end anonymous namespace
Index: clang/unittests/Interpreter/CMakeLists.txt
===
--- clang/unittests/Interpreter/CMakeLists.txt
+++ clang/unittests/Interpreter/CMakeLists.txt
@@ -22,3 +22,5 @@
 if(NOT WIN32)
   add_subdirectory(ExceptionTests)
 endif()
+
+export_executable_symbols(ClangReplInterpreterTests)
Index: clang/tools/clang-repl/CMakeLists.txt
===
--- clang/tools/clang-repl/CMakeLists.txt
+++ clang/tools/clang-repl/CMakeLists.txt
@@ -12,6 +12,7 @@
   )
 
 clang_target_link_libraries(clang-repl PRIVATE
+  clangAST
   clangBasic
   clangFrontend
   clangInterpreter
Index: clang/lib/Parse/Parser.cpp

[PATCH] D147845: [clang][Interp] Fix a crash when calling invalid constexpr functions

2023-04-08 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, shafik, erichkeane, tahonermann.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147845

Files:
  clang/lib/AST/Interp/InterpFrame.cpp
  clang/test/AST/Interp/functions.cpp


Index: clang/test/AST/Interp/functions.cpp
===
--- clang/test/AST/Interp/functions.cpp
+++ clang/test/AST/Interp/functions.cpp
@@ -202,3 +202,20 @@
 constexpr int doit() { return nyd(10); }
 constexpr int nyd(int m) { return m; }
 static_assert(doit() == 10, "");
+
+namespace InvalidCall {
+  struct S {
+constexpr int a() const { // expected-error {{never produces a constant 
expression}} \
+  // ref-error {{never produces a constant 
expression}}
+  return 1 / 0; // expected-note 2{{division by zero}} \
+// expected-warning {{is undefined}} \
+// ref-note 2{{division by zero}} \
+// ref-warning {{is undefined}}
+}
+  };
+  constexpr S s;
+  static_assert(s.a() == 1); // expected-error {{not an integral constant 
expression}} \
+ // expected-note {{in call to}} \
+ // ref-error {{not an integral constant 
expression}} \
+ // ref-note {{in call to}}
+}
Index: clang/lib/AST/Interp/InterpFrame.cpp
===
--- clang/lib/AST/Interp/InterpFrame.cpp
+++ clang/lib/AST/Interp/InterpFrame.cpp
@@ -127,7 +127,8 @@
   }
 
   // Drop the first pointer since we print it unconditionally anyway.
-  Levels.erase(Levels.begin());
+  if (!Levels.empty())
+Levels.erase(Levels.begin());
 
   printDesc(P.getDeclDesc());
   for (const auto  : Levels) {


Index: clang/test/AST/Interp/functions.cpp
===
--- clang/test/AST/Interp/functions.cpp
+++ clang/test/AST/Interp/functions.cpp
@@ -202,3 +202,20 @@
 constexpr int doit() { return nyd(10); }
 constexpr int nyd(int m) { return m; }
 static_assert(doit() == 10, "");
+
+namespace InvalidCall {
+  struct S {
+constexpr int a() const { // expected-error {{never produces a constant expression}} \
+  // ref-error {{never produces a constant expression}}
+  return 1 / 0; // expected-note 2{{division by zero}} \
+// expected-warning {{is undefined}} \
+// ref-note 2{{division by zero}} \
+// ref-warning {{is undefined}}
+}
+  };
+  constexpr S s;
+  static_assert(s.a() == 1); // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to}} \
+ // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to}}
+}
Index: clang/lib/AST/Interp/InterpFrame.cpp
===
--- clang/lib/AST/Interp/InterpFrame.cpp
+++ clang/lib/AST/Interp/InterpFrame.cpp
@@ -127,7 +127,8 @@
   }
 
   // Drop the first pointer since we print it unconditionally anyway.
-  Levels.erase(Levels.begin());
+  if (!Levels.empty())
+Levels.erase(Levels.begin());
 
   printDesc(P.getDeclDesc());
   for (const auto  : Levels) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141215: [clang-repl] Introduce Value to capture expression results

2023-04-08 Thread Jun Zhang via Phabricator via cfe-commits
junaire updated this revision to Diff 511867.
junaire added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141215

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Interpreter/Interpreter.h
  clang/include/clang/Interpreter/Value.h
  clang/include/clang/Parse/Parser.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Frontend/PrintPreprocessedOutput.cpp
  clang/lib/Interpreter/CMakeLists.txt
  clang/lib/Interpreter/IncrementalParser.cpp
  clang/lib/Interpreter/IncrementalParser.h
  clang/lib/Interpreter/Interpreter.cpp
  clang/lib/Interpreter/InterpreterUtils.cpp
  clang/lib/Interpreter/InterpreterUtils.h
  clang/lib/Interpreter/Value.cpp
  clang/lib/Lex/PPLexerChange.cpp
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/Parser.cpp
  clang/tools/clang-repl/CMakeLists.txt
  clang/unittests/Interpreter/CMakeLists.txt
  clang/unittests/Interpreter/InterpreterTest.cpp

Index: clang/unittests/Interpreter/InterpreterTest.cpp
===
--- clang/unittests/Interpreter/InterpreterTest.cpp
+++ clang/unittests/Interpreter/InterpreterTest.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/Mangle.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Interpreter/Value.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Sema.h"
 
@@ -33,6 +34,10 @@
 #define CLANG_INTERPRETER_NO_SUPPORT_EXEC
 #endif
 
+int Global = 42;
+int getGlobal() { return Global; }
+void setGlobal(int val) { Global = val; }
+
 namespace {
 using Args = std::vector;
 static std::unique_ptr
@@ -276,8 +281,7 @@
   std::vector Args = {"-fno-delayed-template-parsing"};
   std::unique_ptr Interp = createInterpreter(Args);
 
-  llvm::cantFail(Interp->Parse("void* operator new(__SIZE_TYPE__, void* __p);"
-   "extern \"C\" int printf(const char*,...);"
+  llvm::cantFail(Interp->Parse("extern \"C\" int printf(const char*,...);"
"class A {};"
"struct B {"
"  template"
@@ -314,4 +318,54 @@
   free(NewA);
 }
 
+TEST(InterpreterTest, Value) {
+  std::unique_ptr Interp = createInterpreter();
+
+  Value V1;
+  llvm::cantFail(Interp->ParseAndExecute("int x = 42;"));
+  llvm::cantFail(Interp->ParseAndExecute("x", ));
+  EXPECT_TRUE(V1.isValid());
+  EXPECT_EQ(V1.getInt(), 42);
+  EXPECT_TRUE(V1.getType()->isIntegerType());
+  EXPECT_EQ(V1.getKind(), Value::K_Int);
+  EXPECT_FALSE(V1.isManuallyAlloc());
+  EXPECT_FALSE(V1.isPointerOrObjectType());
+
+  Value V2;
+  llvm::cantFail(Interp->ParseAndExecute("double y = 3.14;"));
+  llvm::cantFail(Interp->ParseAndExecute("y", ));
+  EXPECT_TRUE(V2.isValid());
+  EXPECT_EQ(V2.getDouble(), 3.14);
+  EXPECT_TRUE(V2.getType()->isFloatingType());
+  EXPECT_EQ(V2.getKind(), Value::K_Double);
+  EXPECT_FALSE(V2.isManuallyAlloc());
+  EXPECT_FALSE(V2.isPointerOrObjectType());
+
+  Value V3;
+  llvm::cantFail(Interp->ParseAndExecute("struct S { int* p; S() { p = new int(42); } ~S() { delete p; }};"));
+  llvm::cantFail(Interp->ParseAndExecute("S{}", ));
+  EXPECT_TRUE(V3.isValid());
+  EXPECT_TRUE(V3.getType()->isRecordType());
+  EXPECT_EQ(V3.getKind(), Value::K_PtrOrObj);
+  EXPECT_TRUE(V3.isManuallyAlloc());
+  EXPECT_TRUE(V3.isPointerOrObjectType());
+
+  Value V4;
+  llvm::cantFail(Interp->ParseAndExecute("int getGlobal();"));
+  llvm::cantFail(Interp->ParseAndExecute("void setGlobal(int);"));
+  llvm::cantFail(Interp->ParseAndExecute("getGlobal()", ));
+  EXPECT_EQ(V4.getInt(), 42);
+  EXPECT_TRUE(V4.getType()->isIntegerType());
+
+  Value V5;
+  // Change the global from the compiled code.
+  setGlobal(43);
+  llvm::cantFail(Interp->ParseAndExecute("getGlobal()", ));
+  EXPECT_EQ(V5.getInt(), 43);
+  EXPECT_TRUE(V5.getType()->isIntegerType());
+
+  // Change the global from the interpreted code.
+  llvm::cantFail(Interp->ParseAndExecute("setGlobal(44);"));
+  EXPECT_EQ(getGlobal(), 44);
+}
 } // end anonymous namespace
Index: clang/unittests/Interpreter/CMakeLists.txt
===
--- clang/unittests/Interpreter/CMakeLists.txt
+++ clang/unittests/Interpreter/CMakeLists.txt
@@ -22,3 +22,5 @@
 if(NOT WIN32)
   add_subdirectory(ExceptionTests)
 endif()
+
+export_executable_symbols(ClangReplInterpreterTests)
Index: clang/tools/clang-repl/CMakeLists.txt
===
--- clang/tools/clang-repl/CMakeLists.txt
+++ clang/tools/clang-repl/CMakeLists.txt
@@ -12,6 +12,7 @@
   )
 
 clang_target_link_libraries(clang-repl PRIVATE
+  clangAST
   clangBasic
   clangFrontend
   clangInterpreter
Index: clang/lib/Parse/Parser.cpp

[PATCH] D144331: [libc++][format] Implements formatter thread::id.

2023-04-08 Thread Mark de Wever via Phabricator via cfe-commits
Mordante updated this revision to Diff 511865.
Mordante added a comment.
Herald added a subscriber: krytarowski.

CI fixes.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144331

Files:
  libcxx/docs/FeatureTestMacroTable.rst
  libcxx/docs/ReleaseNotes.rst
  libcxx/docs/Status/Cxx2b.rst
  libcxx/docs/Status/Cxx2bPapers.csv
  libcxx/docs/Status/FormatPaper.csv
  libcxx/include/__format/parser_std_format_spec.h
  libcxx/include/__threading_support
  libcxx/include/thread
  libcxx/include/version
  libcxx/test/libcxx/transitive_includes/cxx03.csv
  libcxx/test/libcxx/transitive_includes/cxx11.csv
  libcxx/test/libcxx/transitive_includes/cxx14.csv
  libcxx/test/libcxx/transitive_includes/cxx17.csv
  libcxx/test/libcxx/transitive_includes/cxx20.csv
  libcxx/test/libcxx/transitive_includes/cxx2b.csv
  
libcxx/test/std/language.support/support.limits/support.limits.general/thread.version.compile.pass.cpp
  
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.format.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.tests.h
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.functions.vformat.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/format.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/parse.pass.cpp
  
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
  
libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
  libcxx/utils/generate_feature_test_macro_components.py

Index: libcxx/utils/generate_feature_test_macro_components.py
===
--- libcxx/utils/generate_feature_test_macro_components.py
+++ libcxx/utils/generate_feature_test_macro_components.py
@@ -327,6 +327,13 @@
 "test_suite_guard": "!defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
 "libcxx_guard": "!defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
 "unimplemented": True,
+  }, {
+"name": "__cpp_lib_formatters",
+"values": { "c++2b": 202302 },
+"headers": ["stacktrace", "thread"],
+"test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
+"libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
+"unimplemented": True,
   }, {
 "name": "__cpp_lib_forward_like",
 "values": { "c++2b": 202207 },
Index: libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
===
--- libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
+++ libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
@@ -175,7 +175,8 @@
 // Tests for P1636 Formatters for library types
 //
 // The paper hasn't been voted in so currently all formatters are disabled.
-// TODO validate whether the test is correct after the paper has been accepted.
+// Note the paper has been abandoned, the types are kept since other papers may
+// introduce these formatters.
 template 
 void test_P1636() {
   assert_is_not_formattable, CharT>();
@@ -191,7 +192,7 @@
 assert_is_not_formattable, CharT>();
 #endif
 #ifndef TEST_HAS_NO_THREADS
-  assert_is_not_formattable();
+  assert_is_formattable();
 #endif
   assert_is_not_formattable, CharT>();
 }
Index: libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
===
--- libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
+++ libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
@@ -9,6 +9,10 @@
 // UNSUPPORTED: no-threads
 // UNSUPPORTED: no-localization
 
+// TODO FMT This test should not require std::to_chars(floating-point)
+// This test requires std::to_chars(floating-point), which is in the dylib
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0}}
+
 // 
 
 // class thread::id
@@ -18,16 +22,38 @@
 // operator<<(basic_ostream& out, thread::id id);
 
 #include 
+#include 
 #include 
 #include 
 
+#include "make_string.h"
 #include "test_macros.h"
 
-int main(int, char**)
-{
-std::thread::id id0 = std::this_thread::get_id();
-std::ostringstream os;
-os << id0;
+template 
+static void test() {
+  std::thread::id id0 = std::this_thread::get_id();
+  std::basic_ostringstream os;
+  os << id0;
+
+#if TEST_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+  

[PATCH] D147844: Emit warning when implicit cast to bool happens in an conditional operator expression when used inside an overloaded shift operator expression

2023-04-08 Thread NagaChaitanya Vellanki via Phabricator via cfe-commits
chaitanyav added a comment.

output for testcases mentioned in 
https://github.com/llvm/llvm-project/issues/61943

  test.cpp:6:30: warning: overloaded operator << has higher precedence than 
comparison operator [-Woverloaded-shift-op-parentheses]
  std::cout << "Test" << a == 5 ? 1 : 0;
   ^  ~
  test.cpp:6:25: note: place parentheses around the '<<' expression to silence 
this warning
  std::cout << "Test" << a == 5 ? 1 : 0;
  ^
  (   )
  test.cpp:6:30: note: place parentheses around comparison expression to 
evaluate it first
  std::cout << "Test" << a == 5 ? 1 : 0;
   ^
 ( )
  test.cpp:6:30: error: invalid operands to binary expression ('ostream' and 
'int')
  std::cout << "Test" << a == 5 ? 1 : 0;
   ^  ~
  test.cpp:7:30: warning: operator '?:' has lower precedence than '<<'; '<<' 
will be evaluated first [-Wparentheses]
  std::cout << "Test" << a ? 1 : 0;
   ^
  test.cpp:7:30: note: place parentheses around the '<<' expression to silence 
this warning
  std::cout << "Test" << a ? 1 : 0;
   ^
  (   )
  test.cpp:7:30: note: place parentheses around the '?:' expression to evaluate 
it first
  std::cout << "Test" << a ? 1 : 0;
   ^
 ()
  test.cpp:8:49: warning: operator '?:' has lower precedence than '<<'; '<<' 
will be evaluated first [-Wparentheses]
  std::cout << "Test" << static_cast(a) ? 1 : 0;
  ~~~ ^
  test.cpp:8:49: note: place parentheses around the '<<' expression to silence 
this warning
  std::cout << "Test" << static_cast(a) ? 1 : 0;
  ^
  (  )
  test.cpp:8:49: note: place parentheses around the '?:' expression to evaluate 
it first
  std::cout << "Test" << static_cast(a) ? 1 : 0;
  ^

@aaron.ballman Please review


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147844

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


[PATCH] D147844: Emit warning when implicit cast to bool happens in an conditional operator expression when used inside an overloaded shift operator expression

2023-04-08 Thread NagaChaitanya Vellanki via Phabricator via cfe-commits
chaitanyav created this revision.
Herald added a project: All.
chaitanyav requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Fixes issue https://github.com/llvm/llvm-project/issues/61943


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147844

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Sema/parentheses.cpp


Index: clang/test/Sema/parentheses.cpp
===
--- clang/test/Sema/parentheses.cpp
+++ clang/test/Sema/parentheses.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -Wparentheses -fsyntax-only -verify %s
-// RUN: %clang_cc1 -Wparentheses -fsyntax-only -fdiagnostics-parseable-fixits 
%s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -Wparentheses -Woverloaded-shift-op-parentheses 
-fsyntax-only -verify %s
+// RUN: %clang_cc1 -Wparentheses -Woverloaded-shift-op-parentheses 
-fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 bool someConditionFunc();
 
@@ -31,14 +31,14 @@
 
 class Stream {
 public:
-  operator int();
+  operator bool();
   Stream <<(int);
   Stream <<(const char*);
   Stream >>(int);
   Stream >>(const char*);
 };
 
-void f(Stream& s, bool b) {
+void f(Stream& s, bool b, int x) {
   (void)(s << b ? "foo" : "bar"); // expected-warning {{operator '?:' has 
lower precedence than '<<'}} \
   // expected-note {{place parentheses around 
the '<<' expression to silence this warning}} \
   // expected-note {{place parentheses around 
the '?:' expression to evaluate it first}}
@@ -62,6 +62,30 @@
   // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:")"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
   // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:21-[[@LINE-6]]:21}:")"
+
+  void(s << "Test" << x ? "foo" : "bar"); //expected-warning {{operator '?:' 
has lower precedence than '<<'}} \
+ // expected-note {{place parentheses 
around the '<<' expression to silence this warning}} \
+// expected-note {{place parentheses 
around the '?:' expression to evaluate it first}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:8-[[@LINE-3]]:8}:"("
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:24-[[@LINE-4]]:24}:")"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:23-[[@LINE-5]]:23}:"("
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:40-[[@LINE-6]]:40}:")"
+
+  void(s << x == 1 ? "foo": "bar"); //expected-warning {{overloaded operator 
<< has higher precedence than comparison operator}} \
+   //expected-note {{place parentheses around 
the '<<' expression to silence this warning}} \
+  // expected-note {{place parentheses around 
comparison expression to evaluate it first}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:8-[[@LINE-3]]:8}:"("
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:14-[[@LINE-4]]:14}:")"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:13-[[@LINE-5]]:13}:"("
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:19-[[@LINE-6]]:19}:")"
+
+  void(s << static_cast(x) ? "foo" : "bar"); //expected-warning 
{{operator '?:' has lower precedence than '<<'}} \
+  //expected-note {{place 
parentheses around the '<<' expression to silence this warning}} \
+ //expected-note {{place 
parentheses around the '?:' expression to evaluate it first}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:8-[[@LINE-3]]:8}:"("
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:33-[[@LINE-4]]:33}:")"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:13-[[@LINE-5]]:13}:"("
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:49-[[@LINE-6]]:49}:")"
 }
 
 struct S {
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -9304,7 +9304,7 @@
 
   if (!IsArithmeticBinaryExpr(Condition, , ))
 return;
-  if (!ExprLooksBoolean(CondRHS))
+  if (!ExprLooksBoolean(CondRHS) && !ExprLooksBoolean(Condition))
 return;
 
   // The condition is an arithmetic binary expression, with a right-


Index: clang/test/Sema/parentheses.cpp
===
--- clang/test/Sema/parentheses.cpp
+++ clang/test/Sema/parentheses.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -Wparentheses -fsyntax-only -verify %s
-// RUN: %clang_cc1 -Wparentheses -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -Wparentheses -Woverloaded-shift-op-parentheses -fsyntax-only -verify %s
+// RUN: %clang_cc1 -Wparentheses -Woverloaded-shift-op-parentheses -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 bool someConditionFunc();
 
@@ -31,14 +31,14 @@
 
 class Stream {
 public:
-  operator int();
+  operator bool();
   Stream <<(int);
   Stream <<(const char*);
   Stream >>(int);
   

[PATCH] D141215: [clang-repl] Introduce Value to capture expression results

2023-04-08 Thread Vassil Vassilev via Phabricator via cfe-commits
v.g.vassilev added inline comments.



Comment at: clang/include/clang/Interpreter/Interpreter.h:39
+class Parser;
+class CodeGenerator;
 class CompilerInstance;

v.g.vassilev wrote:
> We probably do not need these forward declarations.
Looks like they came back.



Comment at: clang/include/clang/Interpreter/Interpreter.h:67
   create(std::unique_ptr CI);
+  ASTContext () const;
   const CompilerInstance *getCompilerInstance() const;

We should not need this. `CompileDtorCall` can probably do 
`RD->getASTContext()` instead.



Comment at: clang/include/clang/Interpreter/Interpreter.h:104
+
+  Expr *SynthesizeExpr(clang::Expr *E);
+

Let's make this file static.



Comment at: clang/include/clang/Interpreter/Value.h:1
+//===--- Interpreter.h - Incremental Compiation and Execution---*- C++ -*-===//
+//

`Value.h` instead of `Interpreter.h`



Comment at: clang/include/clang/Interpreter/Value.h:17
+
+#include "llvm/Support/Compiler.h"
+#include 

We should probably remove this include as it seems unneeded.



Comment at: clang/lib/Interpreter/IncrementalASTConsumer.cpp:37
+
+void IncrementalASTConsumer::Transform(DeclGroupRef ) {
+  for (Decl *D : DGR) {

Let's inline this function in its caller.



Comment at: clang/lib/Interpreter/IncrementalASTConsumer.cpp:43
+  // Flip the flag.
+  TSD->setValuePrinting(false);
+}

Do we need to do this? I'd prefer to keep some history in `TSD`.



Comment at: clang/lib/Interpreter/IncrementalASTConsumer.h:25
+
+class IncrementalASTConsumer final : public ASTConsumer {
+  Interpreter 

Let's move this class in `IncrementalParser.cpp`. I don't think we need a new 
file here just yet.



Comment at: clang/lib/Interpreter/IncrementalASTConsumer.h:34
+  bool HandleTopLevelDecl(DeclGroupRef DGR) override final;
+  void HandleTranslationUnit(ASTContext ) override final;
+  static bool classof(const clang::ASTConsumer *) { return true; }

We should make all interfaces pass through as all of them are important events 
that codegen needs to know about.



Comment at: clang/lib/Interpreter/IncrementalParser.h:19
 #include "clang/AST/GlobalDecl.h"
-
+#include "clang/Parse/Parser.h"
 #include "llvm/ADT/ArrayRef.h"

We don't need this include if we remove `getParser` which we do not need.



Comment at: clang/lib/Interpreter/IncrementalParser.h:87
+private:
+  CodeGenerator *GetCodeGen() const;
 };

That should not be needed with the new implementation in this patch.



Comment at: clang/lib/Interpreter/Interpreter.cpp:350
   std::list  = IncrParser->getPTUs();
-  if (N > PTUs.size())
+  if (N + InitPTUSize > PTUs.size())
 return llvm::make_error("Operation failed. "

I'd propose `IncrParser->getPTUs()` to return the list starting from 
`InitPTUSize`. That should solve the issue you see.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141215

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


[PATCH] D141215: [clang-repl] Introduce Value to capture expression results

2023-04-08 Thread Jun Zhang via Phabricator via cfe-commits
junaire updated this revision to Diff 511862.
junaire added a comment.

Clean up the patch


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141215

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Interpreter/Interpreter.h
  clang/include/clang/Interpreter/Value.h
  clang/include/clang/Parse/Parser.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Frontend/PrintPreprocessedOutput.cpp
  clang/lib/Interpreter/CMakeLists.txt
  clang/lib/Interpreter/IncrementalASTConsumer.cpp
  clang/lib/Interpreter/IncrementalASTConsumer.h
  clang/lib/Interpreter/IncrementalParser.cpp
  clang/lib/Interpreter/IncrementalParser.h
  clang/lib/Interpreter/Interpreter.cpp
  clang/lib/Interpreter/InterpreterUtils.cpp
  clang/lib/Interpreter/InterpreterUtils.h
  clang/lib/Interpreter/Value.cpp
  clang/lib/Lex/PPLexerChange.cpp
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/Parser.cpp
  clang/tools/clang-repl/CMakeLists.txt
  clang/unittests/Interpreter/CMakeLists.txt
  clang/unittests/Interpreter/InterpreterTest.cpp

Index: clang/unittests/Interpreter/InterpreterTest.cpp
===
--- clang/unittests/Interpreter/InterpreterTest.cpp
+++ clang/unittests/Interpreter/InterpreterTest.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/Mangle.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Interpreter/Value.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Sema.h"
 
@@ -33,6 +34,10 @@
 #define CLANG_INTERPRETER_NO_SUPPORT_EXEC
 #endif
 
+int Global = 42;
+int getGlobal() { return Global; }
+void setGlobal(int val) { Global = val; }
+
 namespace {
 using Args = std::vector;
 static std::unique_ptr
@@ -276,8 +281,7 @@
   std::vector Args = {"-fno-delayed-template-parsing"};
   std::unique_ptr Interp = createInterpreter(Args);
 
-  llvm::cantFail(Interp->Parse("void* operator new(__SIZE_TYPE__, void* __p);"
-   "extern \"C\" int printf(const char*,...);"
+  llvm::cantFail(Interp->Parse("extern \"C\" int printf(const char*,...);"
"class A {};"
"struct B {"
"  template"
@@ -314,4 +318,54 @@
   free(NewA);
 }
 
+TEST(InterpreterTest, Value) {
+  std::unique_ptr Interp = createInterpreter();
+
+  Value V1;
+  llvm::cantFail(Interp->ParseAndExecute("int x = 42;"));
+  llvm::cantFail(Interp->ParseAndExecute("x", ));
+  EXPECT_TRUE(V1.isValid());
+  EXPECT_EQ(V1.getInt(), 42);
+  EXPECT_TRUE(V1.getType()->isIntegerType());
+  EXPECT_EQ(V1.getKind(), Value::K_Int);
+  EXPECT_FALSE(V1.isManuallyAlloc());
+  EXPECT_FALSE(V1.isPointerOrObjectType());
+
+  Value V2;
+  llvm::cantFail(Interp->ParseAndExecute("double y = 3.14;"));
+  llvm::cantFail(Interp->ParseAndExecute("y", ));
+  EXPECT_TRUE(V2.isValid());
+  EXPECT_EQ(V2.getDouble(), 3.14);
+  EXPECT_TRUE(V2.getType()->isFloatingType());
+  EXPECT_EQ(V2.getKind(), Value::K_Double);
+  EXPECT_FALSE(V2.isManuallyAlloc());
+  EXPECT_FALSE(V2.isPointerOrObjectType());
+
+  Value V3;
+  llvm::cantFail(Interp->ParseAndExecute("struct S { int* p; S() { p = new int(42); } ~S() { delete p; }};"));
+  llvm::cantFail(Interp->ParseAndExecute("S{}", ));
+  EXPECT_TRUE(V3.isValid());
+  EXPECT_TRUE(V3.getType()->isRecordType());
+  EXPECT_EQ(V3.getKind(), Value::K_PtrOrObj);
+  EXPECT_TRUE(V3.isManuallyAlloc());
+  EXPECT_TRUE(V3.isPointerOrObjectType());
+
+  Value V4;
+  llvm::cantFail(Interp->ParseAndExecute("int getGlobal();"));
+  llvm::cantFail(Interp->ParseAndExecute("void setGlobal(int);"));
+  llvm::cantFail(Interp->ParseAndExecute("getGlobal()", ));
+  EXPECT_EQ(V4.getInt(), 42);
+  EXPECT_TRUE(V4.getType()->isIntegerType());
+
+  Value V5;
+  // Change the global from the compiled code.
+  setGlobal(43);
+  llvm::cantFail(Interp->ParseAndExecute("getGlobal()", ));
+  EXPECT_EQ(V5.getInt(), 43);
+  EXPECT_TRUE(V5.getType()->isIntegerType());
+
+  // Change the global from the interpreted code.
+  llvm::cantFail(Interp->ParseAndExecute("setGlobal(44);"));
+  EXPECT_EQ(getGlobal(), 44);
+}
 } // end anonymous namespace
Index: clang/unittests/Interpreter/CMakeLists.txt
===
--- clang/unittests/Interpreter/CMakeLists.txt
+++ clang/unittests/Interpreter/CMakeLists.txt
@@ -22,3 +22,5 @@
 if(NOT WIN32)
   add_subdirectory(ExceptionTests)
 endif()
+
+export_executable_symbols(ClangReplInterpreterTests)
Index: clang/tools/clang-repl/CMakeLists.txt
===
--- clang/tools/clang-repl/CMakeLists.txt
+++ clang/tools/clang-repl/CMakeLists.txt
@@ -12,6 +12,7 @@
   )
 
 clang_target_link_libraries(clang-repl PRIVATE
+  clangAST
   

[PATCH] D147843: [clang-tidy] fix hint use correct range to replace last NamespaceDecl

2023-04-08 Thread Congcong Cai via Phabricator via cfe-commits
HerrCai0907 created this revision.
HerrCai0907 added a reviewer: PiotrZSL.
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a reviewer: njames93.
Herald added a project: All.
HerrCai0907 requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

range of replacing last namespace decl should be from last non nested namespace 
to last namespace


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147843

Files:
  clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
===
--- 
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
@@ -105,7 +105,7 @@
 namespace n28 {
 namespace n29::n30 {
 // CHECK-MESSAGES-DAG: :[[@LINE-3]]:1: warning: nested namespaces can be 
concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES: namespace n26::n27::n28::n29::n30
+// CHECK-FIXES: namespace n26::n27::n28::n29::n30 {
 void t() {}
 } // namespace n29::n30
 } // namespace n28
Index: clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
@@ -124,12 +124,12 @@
   SmallVector Backs;
   Backs.reserve(Namespaces.size());
 
-  NamespaceDecl const *LastND = nullptr;
+  NamespaceDecl const *LastNonNestND = nullptr;
 
   for (const NamespaceDecl *ND : Namespaces) {
 if (ND->isNested())
   continue;
-LastND = ND;
+LastNonNestND = ND;
 std::optional SR =
 getCleanedNamespaceFrontRange(ND, SM, LangOpts);
 if (!SR.has_value())
@@ -137,7 +137,7 @@
 Fronts.push_back(SR.value());
 Backs.push_back(getCleanedNamespaceBackRange(ND, SM, LangOpts));
   }
-  if (LastND == nullptr || Fronts.empty() || Backs.empty())
+  if (LastNonNestND == nullptr || Fronts.empty() || Backs.empty())
 return;
   // the last one should be handled specially
   Fronts.pop_back();
@@ -147,9 +147,11 @@
   for (SourceRange const  : Fronts)
 DB << FixItHint::CreateRemoval(Front);
   DB << FixItHint::CreateReplacement(
-  SourceRange{LastND->getBeginLoc(), LastND->getLocation()},
+  SourceRange{LastNonNestND->getBeginLoc(),
+  Namespaces.back()->getLocation()},
   ConcatNameSpace);
-  if (LastRBrace != SourceRange{LastND->getRBraceLoc(), 
LastND->getRBraceLoc()})
+  if (LastRBrace !=
+  SourceRange{LastNonNestND->getRBraceLoc(), 
LastNonNestND->getRBraceLoc()})
 DB << FixItHint::CreateReplacement(LastRBrace,
("} // " + ConcatNameSpace).str());
   for (SourceRange const  : llvm::reverse(Backs))


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
@@ -105,7 +105,7 @@
 namespace n28 {
 namespace n29::n30 {
 // CHECK-MESSAGES-DAG: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES: namespace n26::n27::n28::n29::n30
+// CHECK-FIXES: namespace n26::n27::n28::n29::n30 {
 void t() {}
 } // namespace n29::n30
 } // namespace n28
Index: clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
@@ -124,12 +124,12 @@
   SmallVector Backs;
   Backs.reserve(Namespaces.size());
 
-  NamespaceDecl const *LastND = nullptr;
+  NamespaceDecl const *LastNonNestND = nullptr;
 
   for (const NamespaceDecl *ND : Namespaces) {
 if (ND->isNested())
   continue;
-LastND = ND;
+LastNonNestND = ND;
 std::optional SR =
 getCleanedNamespaceFrontRange(ND, SM, LangOpts);
 if (!SR.has_value())
@@ -137,7 +137,7 @@
 Fronts.push_back(SR.value());
 Backs.push_back(getCleanedNamespaceBackRange(ND, SM, LangOpts));
   }
-  if (LastND == nullptr || Fronts.empty() || Backs.empty())
+  if (LastNonNestND == nullptr || Fronts.empty() || Backs.empty())
 return;
   // the last one should be handled specially
   Fronts.pop_back();
@@ -147,9 +147,11 @@
   for (SourceRange const  : Fronts)
 DB << FixItHint::CreateRemoval(Front);
   DB << FixItHint::CreateReplacement(
-  

[PATCH] D141215: [clang-repl] Introduce Value to capture expression results

2023-04-08 Thread Jun Zhang via Phabricator via cfe-commits
junaire updated this revision to Diff 511857.
junaire added a comment.

Update...


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141215

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Interpreter/Interpreter.h
  clang/include/clang/Interpreter/Value.h
  clang/include/clang/Parse/Parser.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Frontend/PrintPreprocessedOutput.cpp
  clang/lib/Interpreter/CMakeLists.txt
  clang/lib/Interpreter/IncrementalASTConsumer.cpp
  clang/lib/Interpreter/IncrementalASTConsumer.h
  clang/lib/Interpreter/IncrementalExecutor.cpp
  clang/lib/Interpreter/IncrementalExecutor.h
  clang/lib/Interpreter/IncrementalParser.cpp
  clang/lib/Interpreter/IncrementalParser.h
  clang/lib/Interpreter/Interpreter.cpp
  clang/lib/Interpreter/InterpreterUtils.cpp
  clang/lib/Interpreter/InterpreterUtils.h
  clang/lib/Interpreter/Value.cpp
  clang/lib/Lex/PPLexerChange.cpp
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/Parser.cpp
  clang/tools/clang-repl/CMakeLists.txt
  clang/unittests/Interpreter/CMakeLists.txt
  clang/unittests/Interpreter/InterpreterTest.cpp

Index: clang/unittests/Interpreter/InterpreterTest.cpp
===
--- clang/unittests/Interpreter/InterpreterTest.cpp
+++ clang/unittests/Interpreter/InterpreterTest.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/Mangle.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Interpreter/Value.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Sema.h"
 
@@ -33,6 +34,10 @@
 #define CLANG_INTERPRETER_NO_SUPPORT_EXEC
 #endif
 
+int Global = 42;
+int getGlobal() { return Global; }
+void setGlobal(int val) { Global = val; }
+
 namespace {
 using Args = std::vector;
 static std::unique_ptr
@@ -276,8 +281,7 @@
   std::vector Args = {"-fno-delayed-template-parsing"};
   std::unique_ptr Interp = createInterpreter(Args);
 
-  llvm::cantFail(Interp->Parse("void* operator new(__SIZE_TYPE__, void* __p);"
-   "extern \"C\" int printf(const char*,...);"
+  llvm::cantFail(Interp->Parse("extern \"C\" int printf(const char*,...);"
"class A {};"
"struct B {"
"  template"
@@ -314,4 +318,38 @@
   free(NewA);
 }
 
+TEST(InterpreterTest, Value) {
+  std::unique_ptr Interp = createInterpreter();
+
+  Value V1;
+  llvm::cantFail(Interp->ParseAndExecute("int x = 42;"));
+  llvm::cantFail(Interp->ParseAndExecute("x", ));
+  EXPECT_EQ(V1.getInt(), 42);
+  EXPECT_TRUE(V1.getType()->isIntegerType());
+
+  Value V2;
+  llvm::cantFail(Interp->ParseAndExecute("double y = 3.14;"));
+  llvm::cantFail(Interp->ParseAndExecute("y", ));
+  EXPECT_EQ(V2.getAs(), 3.14);
+  EXPECT_TRUE(V2.getType()->isFloatingType());
+  EXPECT_EQ(V2.castAs(), 3);
+
+  llvm::cantFail(Interp->ParseAndExecute("int getGlobal();"));
+  llvm::cantFail(Interp->ParseAndExecute("void setGlobal(int);"));
+  Value V3;
+  llvm::cantFail(Interp->ParseAndExecute("getGlobal()", ));
+  EXPECT_EQ(V3.getInt(), 42);
+  EXPECT_TRUE(V3.getType()->isIntegerType());
+
+  // Change the global from the compiled code.
+  setGlobal(43);
+  Value V4;
+  llvm::cantFail(Interp->ParseAndExecute("getGlobal()", ));
+  EXPECT_EQ(V4.getInt(), 43);
+  EXPECT_TRUE(V4.getType()->isIntegerType());
+
+  // Change the global from the interpreted code.
+  llvm::cantFail(Interp->ParseAndExecute("setGlobal(44);"));
+  EXPECT_EQ(getGlobal(), 44);
+}
 } // end anonymous namespace
Index: clang/unittests/Interpreter/CMakeLists.txt
===
--- clang/unittests/Interpreter/CMakeLists.txt
+++ clang/unittests/Interpreter/CMakeLists.txt
@@ -22,3 +22,5 @@
 if(NOT WIN32)
   add_subdirectory(ExceptionTests)
 endif()
+
+export_executable_symbols(ClangReplInterpreterTests)
Index: clang/tools/clang-repl/CMakeLists.txt
===
--- clang/tools/clang-repl/CMakeLists.txt
+++ clang/tools/clang-repl/CMakeLists.txt
@@ -12,6 +12,7 @@
   )
 
 clang_target_link_libraries(clang-repl PRIVATE
+  clangAST
   clangBasic
   clangFrontend
   clangInterpreter
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -320,6 +320,7 @@
 case tok::annot_module_begin:
 case tok::annot_module_end:
 case tok::annot_module_include:
+case tok::annot_input_end:
   // Stop before we change submodules. They generally indicate a "good"
   // place to pick up parsing again (except in the special case where
   // we're trying to skip to EOF).
@@ -616,8 +617,8 @@
 
   // Skip 

[PATCH] D147615: [clang][Sema][NFC] Save token name instead of the full token

2023-04-08 Thread Timm Bäder via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG11ad7d2935af: [clang][Sema][NFC] Save token name instead of 
the full token (authored by tbaeder).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147615

Files:
  clang/lib/Parse/ParseDeclCXX.cpp


Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -958,8 +958,8 @@
   assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&
  "Not a static_assert declaration");
 
-  // Save the token used for static assertion.
-  Token SavedTok = Tok;
+  // Save the token name used for static assertion.
+  const char *TokName = Tok.getName();
 
   if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11)
 Diag(Tok, diag::ext_c11_feature) << Tok.getName();
@@ -1027,9 +1027,7 @@
   T.consumeClose();
 
   DeclEnd = Tok.getLocation();
-  // Passing the token used to the error message.
-  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert,
-   SavedTok.getName());
+  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);
 
   return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, 
AssertExpr.get(),
   AssertMessage.get(),


Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -958,8 +958,8 @@
   assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&
  "Not a static_assert declaration");
 
-  // Save the token used for static assertion.
-  Token SavedTok = Tok;
+  // Save the token name used for static assertion.
+  const char *TokName = Tok.getName();
 
   if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11)
 Diag(Tok, diag::ext_c11_feature) << Tok.getName();
@@ -1027,9 +1027,7 @@
   T.consumeClose();
 
   DeclEnd = Tok.getLocation();
-  // Passing the token used to the error message.
-  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert,
-   SavedTok.getName());
+  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);
 
   return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, AssertExpr.get(),
   AssertMessage.get(),
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 11ad7d2 - [clang][Sema][NFC] Save token name instead of the full token

2023-04-08 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-04-08T09:02:19+02:00
New Revision: 11ad7d2935afe965c9e8c7ba4732215b404ff57f

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

LOG: [clang][Sema][NFC] Save token name instead of the full token

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

Added: 


Modified: 
clang/lib/Parse/ParseDeclCXX.cpp

Removed: 




diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp 
b/clang/lib/Parse/ParseDeclCXX.cpp
index 037bc869c5a1..1530d824c345 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -958,8 +958,8 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation 
) {
   assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&
  "Not a static_assert declaration");
 
-  // Save the token used for static assertion.
-  Token SavedTok = Tok;
+  // Save the token name used for static assertion.
+  const char *TokName = Tok.getName();
 
   if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11)
 Diag(Tok, diag::ext_c11_feature) << Tok.getName();
@@ -1027,9 +1027,7 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation 
) {
   T.consumeClose();
 
   DeclEnd = Tok.getLocation();
-  // Passing the token used to the error message.
-  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert,
-   SavedTok.getName());
+  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);
 
   return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, 
AssertExpr.get(),
   AssertMessage.get(),



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


[PATCH] D147534: [clang][Interp] Make sure we have a variable scope for initializers

2023-04-08 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added inline comments.



Comment at: clang/test/AST/Interp/records.cpp:315
+  auto T = Test(Arr, Pos);
+  // End of scope, should destroy Test.
+}

aaron.ballman wrote:
> Would it make sense to give `Test` a constexpr destructor so that we can 
> validate it's being called? e.g. https://godbolt.org/z/fhE7xzE4e
That just tests regular destructors, doesn't it? That's already covered by 
other tests.


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

https://reviews.llvm.org/D147534

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


[clang] e7f55bb - [clang][Interp][NFCI] Call* ops don't modify the PC

2023-04-08 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-04-08T08:49:22+02:00
New Revision: e7f55bbdb880eb0c096b05d915ee920fe1f2fb98

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

LOG: [clang][Interp][NFCI] Call* ops don't modify the PC

This caused the reported errors from the Call*() handlers to report the
wrong source location.

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

Added: 


Modified: 
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Opcodes.td

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index afc5f24baf73..1eda38e9fa5b 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1486,28 +1486,29 @@ inline bool ArrayElemPtrPop(InterpState , CodePtr 
OpPC) {
   return NarrowPtr(S, OpPC);
 }
 
-inline bool CheckGlobalCtor(InterpState , CodePtr ) {
+inline bool CheckGlobalCtor(InterpState , CodePtr OpPC) {
   const Pointer  = S.Stk.peek();
-  return CheckCtorCall(S, PC, Obj);
+  return CheckCtorCall(S, OpPC, Obj);
 }
 
-inline bool Call(InterpState , CodePtr , const Function *Func) {
+inline bool Call(InterpState , CodePtr OpPC, const Function *Func) {
   if (Func->hasThisPointer()) {
 size_t ThisOffset =
 Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0);
+
 const Pointer  = S.Stk.peek(ThisOffset);
 
-if (!CheckInvoke(S, PC, ThisPtr))
+if (!CheckInvoke(S, OpPC, ThisPtr))
   return false;
 
 if (S.checkingPotentialConstantExpression())
   return false;
   }
 
-  if (!CheckCallable(S, PC, Func))
+  if (!CheckCallable(S, OpPC, Func))
 return false;
 
-  auto NewFrame = std::make_unique(S, Func, PC);
+  auto NewFrame = std::make_unique(S, Func, OpPC);
   InterpFrame *FrameBefore = S.Current;
   S.Current = NewFrame.get();
 
@@ -1541,14 +1542,14 @@ inline bool CallBI(InterpState , CodePtr , const 
Function *Func) {
   return false;
 }
 
-inline bool CallPtr(InterpState , CodePtr ) {
+inline bool CallPtr(InterpState , CodePtr OpPC) {
   const FunctionPointer  = S.Stk.pop();
 
   const Function *F = FuncPtr.getFunction();
   if (!F || !F->isConstexpr())
 return false;
 
-  return Call(S, PC, F);
+  return Call(S, OpPC, F);
 }
 
 inline bool GetFnPtr(InterpState , CodePtr , const Function *Func) {

diff  --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index f3662dcd6f43..ed0774a78833 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -179,19 +179,16 @@ def NoRet : Opcode {}
 def Call : Opcode {
   let Args = [ArgFunction];
   let Types = [];
-  let ChangesPC = 1;
 }
 
 def CallBI : Opcode {
   let Args = [ArgFunction];
   let Types = [];
-  let ChangesPC = 1;
 }
 
 def CallPtr : Opcode {
   let Args = [];
   let Types = [];
-  let ChangesPC = 1;
 }
 
 
//===--===//



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


[PATCH] D146178: [Clang][Sema] Fix comparison of constraint expressions

2023-04-08 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov updated this revision to Diff 511854.
alexander-shaposhnikov added a comment.

This version is partially based on https://reviews.llvm.org/D147722.
The case with self-friendship is problematic (had to add a workaround, any 
suggestions would be greatly appreciated).
Added more tests.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146178

Files:
  clang/include/clang/Sema/Template.h
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/SemaTemplate/concepts-out-of-line-def.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -816,3 +816,62 @@
 static_assert(Parent::TakesBinary::i == 0);
 }
 
+namespace TemplateInsideNonTemplateClass {
+template concept C = true;
+
+template auto L = [] U>() {};
+
+struct Q {
+  template U> friend constexpr auto decltype(L)::operator()() const;
+};
+} // namespace TemplateInsideNonTemplateClass
+
+namespace GH61959 {
+template 
+concept C = (sizeof(T0) >= 4);
+
+template
+struct Orig { };
+
+template
+struct Orig {
+  template requires C
+  void f() { }
+
+  template requires true
+  void f() { }
+};
+
+template  struct Mod {};
+
+template 
+struct Mod {
+  template  requires C
+  constexpr static int f() { return 1; }
+
+  template  requires C
+  constexpr static int f() { return 2; }
+};
+
+static_assert(Mod::f() == 1);
+static_assert(Mod::f() == 2);
+
+template
+struct Outer {
+  template
+  struct Inner {};
+
+  template
+  struct Inner {
+template
+void foo()  requires C && C && C{}
+template
+void foo()  requires true{}
+  };
+};
+
+void bar() {
+  Outer::Inner I;
+  I.foo();
+}
+}
Index: clang/test/SemaTemplate/concepts-out-of-line-def.cpp
===
--- clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -127,3 +127,220 @@
 static_assert(S::specialization("str") == SPECIALIZATION_REQUIRES);
 
 } // namespace multiple_template_parameter_lists
+
+static constexpr int CONSTRAINED_METHOD_1 = 1;
+static constexpr int CONSTRAINED_METHOD_2 = 2;
+
+namespace constrained_members {
+
+template 
+struct S {
+  template 
+  static constexpr int constrained_method();
+};
+
+template <>
+template 
+constexpr int S<1>::constrained_method() { return CONSTRAINED_METHOD_1; }
+
+template <>
+template 
+constexpr int S<2>::constrained_method() { return CONSTRAINED_METHOD_2; }
+
+static_assert(S<1>::constrained_method() == CONSTRAINED_METHOD_1);
+static_assert(S<2>::constrained_method() == CONSTRAINED_METHOD_2);
+
+
+template 
+concept ConceptT1T2 = true;
+
+template
+struct S12 {
+  template T4>
+  static constexpr int constrained_method();
+};
+
+template<>
+template T5>
+constexpr int S12::constrained_method() { return CONSTRAINED_METHOD_1; }
+
+template<>
+template T5>
+constexpr int S12::constrained_method() { return CONSTRAINED_METHOD_2; }
+
+static_assert(S12::constrained_method() == CONSTRAINED_METHOD_1);
+static_assert(S12::constrained_method() == CONSTRAINED_METHOD_2);
+
+} // namespace constrained members
+
+namespace constrained_members_of_nested_types {
+
+template 
+struct S {
+  struct Inner0 {
+struct Inner1 {
+  template 
+  static constexpr int constrained_method();
+};
+  };
+};
+
+template <>
+template 
+constexpr int S<1>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_1; }
+
+template <>
+template 
+constexpr int S<2>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_2; }
+
+static_assert(S<1>::Inner0::Inner1::constrained_method() == CONSTRAINED_METHOD_1);
+static_assert(S<2>::Inner0::Inner1::constrained_method() == CONSTRAINED_METHOD_2);
+
+
+template 
+concept ConceptT1T2 = true;
+
+template
+struct S12 {
+  struct Inner0 {
+struct Inner1 {
+  template T4>
+  static constexpr int constrained_method();
+};
+  };
+};
+
+template<>
+template T5>
+constexpr int S12::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_1; }
+
+template<>
+template T5>
+constexpr int S12::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_2; }
+
+static_assert(S12::Inner0::Inner1::constrained_method() == CONSTRAINED_METHOD_1);
+static_assert(S12::Inner0::Inner1::constrained_method() == CONSTRAINED_METHOD_2);
+
+} // namespace constrained_members_of_nested_types
+
+namespace constrained_member_sfinae {
+
+template struct S {
+  template
+  static constexpr int constrained_method() requires (sizeof(int[N * 1073741824 + 4]) == 16) {
+return CONSTRAINED_METHOD_1;
+  }
+
+  template
+  static constexpr int