[clang-tools-extra] r371976 - Implement semantic selections.

2019-09-16 Thread Utkarsh Saxena via cfe-commits
Author: usaxena95
Date: Mon Sep 16 04:29:35 2019
New Revision: 371976

URL: http://llvm.org/viewvc/llvm-project?rev=371976&view=rev
Log:
Implement semantic selections.

Summary:
For a given cursor position, it returns ranges that are interesting to the user.
Currently the semantic ranges correspond to the nodes of the syntax trees.

Subscribers: mgorny, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

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

Added:
clang-tools-extra/trunk/clangd/SemanticSelection.cpp
clang-tools-extra/trunk/clangd/SemanticSelection.h
clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp
Modified:
clang-tools-extra/trunk/clangd/CMakeLists.txt
clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt

Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CMakeLists.txt?rev=371976&r1=371975&r2=371976&view=diff
==
--- clang-tools-extra/trunk/clangd/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/CMakeLists.txt Mon Sep 16 04:29:35 2019
@@ -66,6 +66,7 @@ add_clang_library(clangDaemon
   RIFF.cpp
   Selection.cpp
   SemanticHighlighting.cpp
+  SemanticSelection.cpp
   SourceCode.cpp
   QueryDriverDatabase.cpp
   Threading.cpp

Added: clang-tools-extra/trunk/clangd/SemanticSelection.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticSelection.cpp?rev=371976&view=auto
==
--- clang-tools-extra/trunk/clangd/SemanticSelection.cpp (added)
+++ clang-tools-extra/trunk/clangd/SemanticSelection.cpp Mon Sep 16 04:29:35 
2019
@@ -0,0 +1,64 @@
+//===--- SemanticSelection.cpp ---*- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+#include "SemanticSelection.h"
+#include "ParsedAST.h"
+#include "Protocol.h"
+#include "Selection.h"
+#include "SourceCode.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+// Adds Range \p R to the Result if it is distinct from the last added Range.
+// Assumes that only consecutive ranges can coincide.
+void addIfDistinct(const Range &R, std::vector &Result) {
+  if (Result.empty() || Result.back() != R) {
+Result.push_back(R);
+  }
+}
+} // namespace
+
+llvm::Expected> getSemanticRanges(ParsedAST &AST,
+ Position Pos) {
+  std::vector Result;
+  const auto &SM = AST.getSourceManager();
+  const auto &LangOpts = AST.getASTContext().getLangOpts();
+
+  auto FID = SM.getMainFileID();
+  auto Offset = positionToOffset(SM.getBufferData(FID), Pos);
+  if (!Offset) {
+return Offset.takeError();
+  }
+
+  // Get node under the cursor.
+  SelectionTree ST(AST.getASTContext(), AST.getTokens(), *Offset);
+  for (const auto *Node = ST.commonAncestor(); Node != nullptr;
+   Node = Node->Parent) {
+if (const Decl *D = Node->ASTNode.get()) {
+  if (llvm::isa(D)) {
+break;
+  }
+}
+
+auto SR = toHalfOpenFileRange(SM, LangOpts, 
Node->ASTNode.getSourceRange());
+if (!SR.hasValue() || SM.getFileID(SR->getBegin()) != SM.getMainFileID()) {
+  continue;
+}
+Range R;
+R.start = sourceLocToPosition(SM, SR->getBegin());
+R.end = sourceLocToPosition(SM, SR->getEnd());
+addIfDistinct(R, Result);
+  }
+  return Result;
+}
+
+} // namespace clangd
+} // namespace clang

Added: clang-tools-extra/trunk/clangd/SemanticSelection.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticSelection.h?rev=371976&view=auto
==
--- clang-tools-extra/trunk/clangd/SemanticSelection.h (added)
+++ clang-tools-extra/trunk/clangd/SemanticSelection.h Mon Sep 16 04:29:35 2019
@@ -0,0 +1,32 @@
+//===--- SemanticSelection.h -*- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// Features for giving interesting semantic ranges around the cursor.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICSELECTION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICSELECTION_H
+#include "ParsedAST.h"
+#include "Protocol.h"
+#in

[clang-tools-extra] r372102 - Add SemanticRanges to Clangd server.

2019-09-17 Thread Utkarsh Saxena via cfe-commits
Author: usaxena95
Date: Tue Sep 17 03:28:05 2019
New Revision: 372102

URL: http://llvm.org/viewvc/llvm-project?rev=372102&view=rev
Log:
Add SemanticRanges to Clangd server.

Summary:
Adds Semantic Ranges capabilities to Clangd server.
Also adds tests for running it via clangd server.

This differs from the LSP spec as the spec needs this to be evaluated on 
multiple 'pos' and the expected output is an list of list of semantic ranges.
This is majorly for multi cursor and assuming this is a rare thing, we don't 
want to optimize make things complicated just for this.
This should be done in the LSP level by queueing one request per 'pos' in the 
input.

LSP Spec:
https://github.com/microsoft/language-server-protocol/blob/dbaeumer/3.15/specification.md#textDocument_selectionRange

Reviewers: hokein

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

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

Modified:
clang-tools-extra/trunk/clangd/ClangdServer.cpp
clang-tools-extra/trunk/clangd/ClangdServer.h
clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp
clang-tools-extra/trunk/clangd/unittests/SyncAPI.cpp
clang-tools-extra/trunk/clangd/unittests/SyncAPI.h

Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=372102&r1=372101&r2=372102&view=diff
==
--- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Tue Sep 17 03:28:05 2019
@@ -17,6 +17,7 @@
 #include "Preamble.h"
 #include "Protocol.h"
 #include "SemanticHighlighting.h"
+#include "SemanticSelection.h"
 #include "SourceCode.h"
 #include "TUScheduler.h"
 #include "Trace.h"
@@ -125,8 +126,8 @@ ClangdServer::ClangdServer(const GlobalC
   // critical paths.
   WorkScheduler(
   CDB, Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory,
-  std::make_unique(
-  DynamicIdx.get(), DiagConsumer, Opts.SemanticHighlighting),
+  std::make_unique(DynamicIdx.get(), 
DiagConsumer,
+ Opts.SemanticHighlighting),
   Opts.UpdateDebounce, Opts.RetentionPolicy) {
   // Adds an index to the stack, at higher priority than existing indexes.
   auto AddIndex = [&](SymbolIndex *Idx) {
@@ -620,6 +621,17 @@ void ClangdServer::symbolInfo(PathRef Fi
   WorkScheduler.runWithAST("SymbolInfo", File, std::move(Action));
 }
 
+void ClangdServer::semanticRanges(PathRef File, Position Pos,
+  Callback> CB) {
+  auto Action =
+  [Pos, CB = std::move(CB)](llvm::Expected InpAST) mutable {
+if (!InpAST)
+  return CB(InpAST.takeError());
+CB(clangd::getSemanticRanges(InpAST->AST, Pos));
+  };
+  WorkScheduler.runWithAST("SemanticRanges", File, std::move(Action));
+}
+
 std::vector>
 ClangdServer::getUsedBytesPerFile() const {
   return WorkScheduler.getUsedBytesPerFile();

Modified: clang-tools-extra/trunk/clangd/ClangdServer.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=372102&r1=372101&r2=372102&view=diff
==
--- clang-tools-extra/trunk/clangd/ClangdServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue Sep 17 03:28:05 2019
@@ -277,6 +277,10 @@ public:
   void symbolInfo(PathRef File, Position Pos,
   Callback> CB);
 
+  /// Get semantic ranges around a specified position in a file.
+  void semanticRanges(PathRef File, Position Pos,
+  Callback> CB);
+
   /// Returns estimated memory usage for each of the currently open files.
   /// The order of results is unspecified.
   /// Overall memory usage of clangd may be significantly more than reported

Modified: clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp?rev=372102&r1=372101&r2=372102&view=diff
==
--- clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp 
(original)
+++ clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp Tue Sep 
17 03:28:05 2019
@@ -7,10 +7,13 @@
 
//===--===//
 
 #include "Annotations.h"
+#include "ClangdServer.h"
 #include "Matchers.h"
 #include "Protocol.h"
 #include "SemanticSelection.h"
 #include "SourceCode.h"
+#include "SyncAPI.h"
+#include "TestFS.h"
 #include "TestTU.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
@@ -23,6 +26,11 @@ namespace clangd {
 namespace {
 using ::testing::ElementsAreArray;
 
+class IgnoreDiagnostics : public Diagno

[clang-tools-extra] r372753 - [clangd] Add semantic selection to ClangdLSPServer.

2019-09-24 Thread Utkarsh Saxena via cfe-commits
Author: usaxena95
Date: Tue Sep 24 06:38:33 2019
New Revision: 372753

URL: http://llvm.org/viewvc/llvm-project?rev=372753&view=rev
Log:
[clangd] Add semantic selection to ClangdLSPServer.

Summary:
This adds semantic selection to the LSP Server.
Adds support for serialization of input request and the output reply.
Also adds regression tests for the feature.

Currently we do not support multi cursor.The LSP Server only accepts single 
position in the request as opposed to many position in the spec.

Spec:
https://github.com/microsoft/language-server-protocol/blob/dbaeumer/3.15/specification.md#textDocument_selectionRange

Reviewers: hokein

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

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

Added:
clang-tools-extra/trunk/clangd/test/selection-range.test
Modified:
clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
clang-tools-extra/trunk/clangd/ClangdLSPServer.h
clang-tools-extra/trunk/clangd/Protocol.cpp
clang-tools-extra/trunk/clangd/Protocol.h
clang-tools-extra/trunk/clangd/test/initialize-params.test

Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=372753&r1=372752&r2=372753&view=diff
==
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Tue Sep 24 06:38:33 2019
@@ -22,14 +22,18 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/JSON.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/SHA1.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include 
+#include 
 #include 
+#include 
 
 namespace clang {
 namespace clangd {
@@ -127,6 +131,21 @@ llvm::Error validateEdits(const DraftSto
   llvm::to_string(InvalidFileCount - 1) + " others)");
 }
 
+// Converts a list of Ranges to a LinkedList of SelectionRange.
+SelectionRange render(const std::vector &Ranges) {
+  if (Ranges.empty())
+return {};
+  SelectionRange Result;
+  Result.range = Ranges[0];
+  auto *Next = &Result.parent;
+  for (const auto &R : llvm::make_range(Ranges.begin() + 1, Ranges.end())) {
+*Next = std::make_unique();
+Next->get()->range = R;
+Next = &Next->get()->parent;
+  }
+  return Result;
+}
+
 } // namespace
 
 // MessageHandler dispatches incoming LSP messages.
@@ -536,6 +555,7 @@ void ClangdLSPServer::onInitialize(const
 {"documentHighlightProvider", true},
 {"hoverProvider", true},
 {"renameProvider", std::move(RenameProvider)},
+{"selectionRangeProvider", true},
 {"documentSymbolProvider", true},
 {"workspaceSymbolProvider", true},
 {"referencesProvider", true},
@@ -1125,6 +1145,30 @@ void ClangdLSPServer::onSymbolInfo(const
  std::move(Reply));
 }
 
+void ClangdLSPServer::onSelectionRange(
+const SelectionRangeParams &Params,
+Callback> Reply) {
+  if (Params.positions.size() != 1) {
+elog("{0} positions provided to SelectionRange. Supports exactly one "
+ "position.",
+ Params.positions.size());
+return Reply(llvm::make_error(
+"SelectionRange supports exactly one position",
+ErrorCode::InvalidRequest));
+  }
+  Server->semanticRanges(
+  Params.textDocument.uri.file(), Params.positions[0],
+  [Reply = std::move(Reply)](
+  llvm::Expected> Ranges) mutable {
+if (!Ranges) {
+  return Reply(Ranges.takeError());
+}
+std::vector Result;
+Result.emplace_back(render(std::move(*Ranges)));
+return Reply(std::move(Result));
+  });
+}
+
 ClangdLSPServer::ClangdLSPServer(
 class Transport &Transp, const FileSystemProvider &FSProvider,
 const clangd::CodeCompleteOptions &CCOpts,
@@ -1167,6 +1211,7 @@ ClangdLSPServer::ClangdLSPServer(
   MsgHandler->bind("textDocument/symbolInfo", &ClangdLSPServer::onSymbolInfo);
   MsgHandler->bind("textDocument/typeHierarchy", 
&ClangdLSPServer::onTypeHierarchy);
   MsgHandler->bind("typeHierarchy/resolve", 
&ClangdLSPServer::onResolveTypeHierarchy);
+  MsgHandler->bind("textDocument/selectionRange", 
&ClangdLSPServer::onSelectionRange);
   // clang-format on
 }
 

Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=372753&r1=372752&r2=372753&view=diff
==
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h Tue Sep 24 06:38:33 2019
@

r373910 - [clang] Add test for FindNextToken in Lexer.

2019-10-07 Thread Utkarsh Saxena via cfe-commits
Author: usaxena95
Date: Mon Oct  7 07:20:46 2019
New Revision: 373910

URL: http://llvm.org/viewvc/llvm-project?rev=373910&view=rev
Log:
[clang] Add test for FindNextToken in Lexer.

Reviewers: ilya-biryukov

Subscribers: cfe-commits

Tags: #clang

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

Modified:
cfe/trunk/unittests/Lex/LexerTest.cpp

Modified: cfe/trunk/unittests/Lex/LexerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Lex/LexerTest.cpp?rev=373910&r1=373909&r2=373910&view=diff
==
--- cfe/trunk/unittests/Lex/LexerTest.cpp (original)
+++ cfe/trunk/unittests/Lex/LexerTest.cpp Mon Oct  7 07:20:46 2019
@@ -11,9 +11,11 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
+#include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Lex/MacroArgs.h"
@@ -21,11 +23,13 @@
 #include "clang/Lex/ModuleLoader.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
-
-using namespace clang;
+#include 
 
 namespace {
+using namespace clang;
+using testing::ElementsAre;
 
 // The test fixture.
 class LexerTest : public ::testing::Test {
@@ -535,4 +539,21 @@ TEST_F(LexerTest, CharRangeOffByOne) {
   EXPECT_EQ(Lexer::getSourceText(CR, SourceMgr, LangOpts), "MOO"); // Was "MO".
 }
 
+TEST_F(LexerTest, FindNextToken) {
+  Lex("int abcd = 0;\n"
+  "int xyz = abcd;\n");
+  std::vector GeneratedByNextToken;
+  SourceLocation Loc =
+  SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
+  while (true) {
+auto T = Lexer::findNextToken(Loc, SourceMgr, LangOpts);
+ASSERT_TRUE(T.hasValue());
+if (T->is(tok::eof))
+  break;
+GeneratedByNextToken.push_back(getSourceText(*T, *T));
+Loc = T->getLocation();
+  }
+  EXPECT_THAT(GeneratedByNextToken, ElementsAre("abcd", "=", "0", ";", "int",
+"xyz", "=", "abcd", ";"));
+}
 } // anonymous namespace


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


[clang-tools-extra] r374982 - [clangd] Add RemoveUsingNamespace tweak.

2019-10-16 Thread Utkarsh Saxena via cfe-commits
Author: usaxena95
Date: Wed Oct 16 02:53:59 2019
New Revision: 374982

URL: http://llvm.org/viewvc/llvm-project?rev=374982&view=rev
Log:
[clangd] Add RemoveUsingNamespace tweak.

Summary:
Removes the 'using namespace' under the cursor and qualifies all accesses in 
the current file.
E.g.:
  using namespace std;
  vector foo(std::map);
Would become:
  std::vector foo(std::map);

Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, mgrang, arphaman, 
kadircet, cfe-commits

Tags: #clang

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

Added:
clang-tools-extra/trunk/clangd/refactor/tweaks/RemoveUsingNamespace.cpp
Modified:
clang-tools-extra/trunk/clangd/AST.cpp
clang-tools-extra/trunk/clangd/AST.h
clang-tools-extra/trunk/clangd/refactor/tweaks/CMakeLists.txt
clang-tools-extra/trunk/clangd/unittests/TweakTests.cpp

Modified: clang-tools-extra/trunk/clangd/AST.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/AST.cpp?rev=374982&r1=374981&r2=374982&view=diff
==
--- clang-tools-extra/trunk/clangd/AST.cpp (original)
+++ clang-tools-extra/trunk/clangd/AST.cpp Wed Oct 16 02:53:59 2019
@@ -115,6 +115,18 @@ static NestedNameSpecifier *getQualifier
   return nullptr;
 }
 
+std::string printUsingNamespaceName(const ASTContext &Ctx,
+const UsingDirectiveDecl &D) {
+  PrintingPolicy PP(Ctx.getLangOpts());
+  std::string Name;
+  llvm::raw_string_ostream Out(Name);
+
+  if (auto *Qual = D.getQualifier())
+Qual->print(Out, PP);
+  D.getNominatedNamespaceAsWritten()->printName(Out);
+  return Out.str();
+}
+
 std::string printName(const ASTContext &Ctx, const NamedDecl &ND) {
   std::string Name;
   llvm::raw_string_ostream Out(Name);

Modified: clang-tools-extra/trunk/clangd/AST.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/AST.h?rev=374982&r1=374981&r2=374982&view=diff
==
--- clang-tools-extra/trunk/clangd/AST.h (original)
+++ clang-tools-extra/trunk/clangd/AST.h Wed Oct 16 02:53:59 2019
@@ -42,6 +42,12 @@ std::string printQualifiedName(const Nam
 /// Returns the first enclosing namespace scope starting from \p DC.
 std::string printNamespaceScope(const DeclContext &DC);
 
+/// Returns the name of the namespace inside the 'using namespace' directive, 
as
+/// written in the code. E.g., passing 'using namespace ::std' will result in
+/// '::std'.
+std::string printUsingNamespaceName(const ASTContext &Ctx,
+const UsingDirectiveDecl &D);
+
 /// Prints unqualified name of the decl for the purpose of displaying it to the
 /// user. Anonymous decls return names of the form "(anonymous {kind})", e.g.
 /// "(anonymous struct)" or "(anonymous namespace)".

Modified: clang-tools-extra/trunk/clangd/refactor/tweaks/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/refactor/tweaks/CMakeLists.txt?rev=374982&r1=374981&r2=374982&view=diff
==
--- clang-tools-extra/trunk/clangd/refactor/tweaks/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/refactor/tweaks/CMakeLists.txt Wed Oct 16 
02:53:59 2019
@@ -19,6 +19,7 @@ add_clang_library(clangDaemonTweaks OBJE
   ExtractFunction.cpp
   ExtractVariable.cpp
   RawStringLiteral.cpp
+  RemoveUsingNamespace.cpp
   SwapIfBranches.cpp
 
   LINK_LIBS

Added: clang-tools-extra/trunk/clangd/refactor/tweaks/RemoveUsingNamespace.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/refactor/tweaks/RemoveUsingNamespace.cpp?rev=374982&view=auto
==
--- clang-tools-extra/trunk/clangd/refactor/tweaks/RemoveUsingNamespace.cpp 
(added)
+++ clang-tools-extra/trunk/clangd/refactor/tweaks/RemoveUsingNamespace.cpp Wed 
Oct 16 02:53:59 2019
@@ -0,0 +1,206 @@
+//===--- RemoveUsingNamespace.cpp *- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+#include "AST.h"
+#include "FindTarget.h"
+#include "Selection.h"
+#include "SourceCode.h"
+#include "refactor/Tweak.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "clang/Tooling/Refactoring/RecursiveSymbolVisitor.h"
+#include "llvm/ADT/ScopeExit.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+/// Removes the 'using namespace' under the cursor and qualifies all accesses 

[clang-tools-extra] a11ec00 - FoldingRanges: Handle LineFoldingsOnly clients.

2022-08-29 Thread Utkarsh Saxena via cfe-commits

Author: Utkarsh Saxena
Date: 2022-08-29T19:03:48+02:00
New Revision: a11ec00afea327419ec1ab7c78ba6818d6c5bbf7

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

LOG: FoldingRanges: Handle LineFoldingsOnly clients.

Do not fold the endline which contains tokens after the end of range.

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

Added: 


Modified: 
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/Protocol.cpp
clang-tools-extra/clangd/Protocol.h
clang-tools-extra/clangd/SemanticSelection.cpp
clang-tools-extra/clangd/SemanticSelection.h
clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp 
b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 66bda05d00f71..e0129d99d9706 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -514,6 +514,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams 
&Params,
   Params.capabilities.HierarchicalDocumentSymbol;
   SupportFileStatus = Params.initializationOptions.FileStatus;
   HoverContentFormat = Params.capabilities.HoverContentFormat;
+  Opts.LineFoldingOnly = Params.capabilities.LineFoldingOnly;
   SupportsOffsetsInSignatureHelp = Params.capabilities.OffsetsInSignatureHelp;
   if (Params.capabilities.WorkDoneProgress)
 BackgroundIndexProgressState = BackgroundIndexProgress::Empty;

diff  --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 2997823e75fc3..5c4263d0ee6cb 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -177,6 +177,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase 
&CDB,
   DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr),
   ClangTidyProvider(Opts.ClangTidyProvider),
   UseDirtyHeaders(Opts.UseDirtyHeaders),
+  LineFoldingOnly(Opts.LineFoldingOnly),
   PreambleParseForwardingFunctions(Opts.PreambleParseForwardingFunctions),
   WorkspaceRoot(Opts.WorkspaceRoot),
   Transient(Opts.ImplicitCancellation ? TUScheduler::InvalidateOnUpdate
@@ -855,8 +856,9 @@ void ClangdServer::foldingRanges(llvm::StringRef File,
 return CB(llvm::make_error(
 "trying to compute folding ranges for non-added document",
 ErrorCode::InvalidParams));
-  auto Action = [CB = std::move(CB), Code = std::move(*Code)]() mutable {
-CB(clangd::getFoldingRanges(Code));
+  auto Action = [LineFoldingOnly = LineFoldingOnly, CB = std::move(CB),
+ Code = std::move(*Code)]() mutable {
+CB(clangd::getFoldingRanges(Code, LineFoldingOnly));
   };
   // We want to make sure folding ranges are always available for all the open
   // files, hence prefer runQuick to not wait for operations on other files.

diff  --git a/clang-tools-extra/clangd/ClangdServer.h 
b/clang-tools-extra/clangd/ClangdServer.h
index b14391aab6680..6be0c930ded47 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -164,6 +164,9 @@ class ClangdServer {
 /// Enable preview of FoldingRanges feature.
 bool FoldingRanges = false;
 
+// Whether the client supports folding only complete lines.
+bool LineFoldingOnly = false;
+
 FeatureModuleSet *FeatureModules = nullptr;
 /// If true, use the dirty buffer contents when building Preambles.
 bool UseDirtyHeaders = false;
@@ -429,6 +432,9 @@ class ClangdServer {
 
   bool UseDirtyHeaders = false;
 
+  // Whether the client supports folding only complete lines.
+  bool LineFoldingOnly = false;
+
   bool PreambleParseForwardingFunctions = false;
 
   // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)

diff  --git a/clang-tools-extra/clangd/Protocol.cpp 
b/clang-tools-extra/clangd/Protocol.cpp
index 0109fa01e34e5..8b833c0f3f8b2 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -391,6 +391,10 @@ bool fromJSON(const llvm::json::Value &Params, 
ClientCapabilities &R,
 }
   }
 }
+if (auto *Folding = TextDocument->getObject("foldingRange")) {
+  if (auto LineFolding = Folding->getBoolean("lineFoldingOnly"))
+R.LineFoldingOnly = *LineFolding;
+}
 if (auto *Rename = TextDocument->getObject("rename")) {
   if (auto RenameSupport = Rename->getBoolean("prepareSupport"))
 R.RenamePrepareSupport = *RenameSupport;

diff  --git a/clang-tools-extra/clangd/Protocol.h 
b/clang-tools-extra/clangd/Protocol.h
index 9a68a33cfb334..aa7c753a9f916 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools

[clang-tools-extra] c338735 - [clangd] Enable folding ranges by default.

2022-08-30 Thread Utkarsh Saxena via cfe-commits

Author: Utkarsh Saxena
Date: 2022-08-30T12:04:59+02:00
New Revision: c338735020033e49fe36369ce3e49e316b6d2da0

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

LOG: [clangd] Enable folding ranges by default.

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

Added: 


Modified: 
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/test/initialize-params.test
clang-tools-extra/clangd/tool/ClangdMain.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp 
b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index e0129d99d9706..449ac9e3a85bd 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -584,6 +584,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams 
&Params,
   {"callHierarchyProvider", true},
   {"clangdInlayHintsProvider", true},
   {"inlayHintProvider", true},
+  {"foldingRangeProvider", true},
   };
 
   {
@@ -613,8 +614,6 @@ void ClangdLSPServer::onInitialize(const InitializeParams 
&Params,
  CodeAction::INFO_KIND}}}
   : llvm::json::Value(true);
 
-  if (Opts.FoldingRanges)
-ServerCaps["foldingRangeProvider"] = true;
 
   std::vector Commands;
   for (llvm::StringRef Command : Handlers.CommandHandlers.keys())
@@ -1618,8 +1617,7 @@ void ClangdLSPServer::bindMethods(LSPBinder &Bind,
   Bind.method("clangd/inlayHints", this, &ClangdLSPServer::onClangdInlayHints);
   Bind.method("textDocument/inlayHint", this, &ClangdLSPServer::onInlayHint);
   Bind.method("$/memoryUsage", this, &ClangdLSPServer::onMemoryUsage);
-  if (Opts.FoldingRanges)
-Bind.method("textDocument/foldingRange", this, 
&ClangdLSPServer::onFoldingRange);
+  Bind.method("textDocument/foldingRange", this, 
&ClangdLSPServer::onFoldingRange);
   Bind.command(ApplyFixCommand, this, &ClangdLSPServer::onCommandApplyEdit);
   Bind.command(ApplyTweakCommand, this, &ClangdLSPServer::onCommandApplyTweak);
 

diff  --git a/clang-tools-extra/clangd/ClangdServer.h 
b/clang-tools-extra/clangd/ClangdServer.h
index 6be0c930ded47..13eed0784c589 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -161,9 +161,6 @@ class ClangdServer {
 /// fetch system include path.
 std::vector QueryDriverGlobs;
 
-/// Enable preview of FoldingRanges feature.
-bool FoldingRanges = false;
-
 // Whether the client supports folding only complete lines.
 bool LineFoldingOnly = false;
 

diff  --git a/clang-tools-extra/clangd/test/initialize-params.test 
b/clang-tools-extra/clangd/test/initialize-params.test
index 8387fb9b504be..e7810c66f44a2 100644
--- a/clang-tools-extra/clangd/test/initialize-params.test
+++ b/clang-tools-extra/clangd/test/initialize-params.test
@@ -43,6 +43,7 @@
 # CHECK-NEXT:  "clangd.applyTweak"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "foldingRangeProvider": true,
 # CHECK-NEXT:  "hoverProvider": true,
 # CHECK-NEXT:  "implementationProvider": true,
 # CHECK-NEXT:  "inlayHintProvider": true,

diff  --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp 
b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 76cfaf7a35dfe..11c5acb71d978 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -308,6 +308,8 @@ RetiredFlag 
CollectMainFileRefs("collect-main-file-refs");
 RetiredFlag CrossFileRename("cross-file-rename");
 RetiredFlag ClangTidyChecks("clang-tidy-checks");
 RetiredFlag InlayHints("inlay-hints");
+RetiredFlag FoldingRanges("folding-ranges");
+
 
 opt LimitResults{
 "limit-results",
@@ -333,14 +335,6 @@ list TweakList{
 CommaSeparated,
 };
 
-opt FoldingRanges{
-"folding-ranges",
-cat(Features),
-desc("Enable preview of FoldingRanges feature"),
-init(false),
-Hidden,
-};
-
 opt WorkerThreadsCount{
 "j",
 cat(Misc),
@@ -903,7 +897,6 @@ clangd accepts flags on the commandline, and in the 
CLANGD_FLAGS environment var
 Opts.StaticIndex = PAI.get();
   }
   Opts.AsyncThreadsCount = WorkerThreadsCount;
-  Opts.FoldingRanges = FoldingRanges;
   Opts.MemoryCleanup = getMemoryCleanupFunction();
 
   Opts.CodeComplete.IncludeIneligibleResults = IncludeIneligibleResults;



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


[clang] e7eec38 - [clang] Skip re-building lambda expressions in parameters to consteval fns.

2022-09-02 Thread Utkarsh Saxena via cfe-commits

Author: Utkarsh Saxena
Date: 2022-09-02T12:30:52+02:00
New Revision: e7eec38246560781e0a4020b19c7eb038a8c5655

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

LOG: [clang] Skip re-building lambda expressions in parameters to consteval fns.

As discussed in this 
[comment](https://github.com/llvm/llvm-project/issues/56183#issuecomment-1224331699),
we end up building the lambda twice: once while parsing the function calls and 
then again while handling the immediate invocation.

This happens specially during removing nested immediate invocation.
Eg: When we have another consteval function as the parameter along with this 
lambda expression. Eg: `foo(bar([]{}))`, `foo(bar(), []{})`

While removing such nested immediate invocations, we should not rebuild this 
lambda. (IIUC, rebuilding a lambda would always generate a new type which will 
never match the original type from parsing)

Fixes: https://github.com/llvm/llvm-project/issues/56183
Fixes: https://github.com/llvm/llvm-project/issues/51695
Fixes: https://github.com/llvm/llvm-project/issues/50455
Fixes: https://github.com/llvm/llvm-project/issues/54872
Fixes: https://github.com/llvm/llvm-project/issues/54587

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

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/cxx2a-consteval.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 41fb9e4035e69..2a92f65cc04fc 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -211,9 +211,16 @@ C++20 Feature Support
 - Correctly set expression evaluation context as 'immediate function context' 
in
   consteval functions.
   This fixes `GH51182 `
+
 - Fixes an assert crash caused by looking up missing vtable information on 
``consteval``
   virtual functions. Fixes `GH55065 
`_.
 
+- Skip rebuilding lambda expressions in arguments of immediate invocations.
+  This fixes `GH56183 `_,
+  `GH51695 `_,
+  `GH50455 `_,
+  `GH54872 `_,
+  `GH54587 `_.
 
 C++2b Feature Support
 ^

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 80ac6733cbef2..f124ad3bc08d0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17598,6 +17598,11 @@ static void RemoveNestedImmediateInvocation(
   DRSet.erase(E);
   return E;
 }
+ExprResult TransformLambdaExpr(LambdaExpr *E) {
+  // Do not rebuild lambdas to avoid creating a new type.
+  // Lambdas have already been processed inside their eval context.
+  return E;
+}
 bool AlwaysRebuild() { return false; }
 bool ReplacingOriginal() { return true; }
 bool AllowSkippingCXXConstructExpr() {

diff  --git a/clang/test/SemaCXX/cxx2a-consteval.cpp 
b/clang/test/SemaCXX/cxx2a-consteval.cpp
index 09129a27818d3..1a8097797bc3c 100644
--- a/clang/test/SemaCXX/cxx2a-consteval.cpp
+++ b/clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -939,3 +939,82 @@ consteval T mid(const T& a, const T& b, const T& c) {
 static_assert(max(1,2)==2);
 static_assert(mid(1,2,3)==2);
 } // namespace GH51182
+
+// https://github.com/llvm/llvm-project/issues/56183
+namespace GH56183 {
+consteval auto Foo(auto c) { return c; }
+consteval auto Bar(auto f) { return f(); }
+void test() {
+  constexpr auto x = Foo(Bar([] { return 'a'; }));
+  static_assert(x == 'a');
+}
+}  // namespace GH56183
+
+// https://github.com/llvm/llvm-project/issues/51695
+namespace GH51695 {
+// Original 
+template 
+struct type_t {};
+
+template 
+struct list_t {};
+
+template 
+consteval auto pop_front(list_t) -> auto {
+  return list_t{};
+}
+
+template 
+consteval auto apply(list_t, F fn) -> auto {
+  return fn(type_t{}...);
+}
+
+void test1() {
+  constexpr auto x = apply(pop_front(list_t{}),
+[](type_t...) { return 42; });
+  static_assert(x == 42);
+}
+// Reduced 1 
+consteval bool zero() { return false; }
+
+template 
+consteval bool foo(bool, F f) {
+  return f();
+}
+
+void test2() {
+  constexpr auto x = foo(zero(), []() { return true; });
+  static_assert(x);
+}
+
+// Reduced 2 
+template 
+consteval auto bar(F f) { return f;}
+
+void test3() {
+  constexpr auto t1 = bar(bar(bar(bar([]() { return true; }();
+  static_assert(t1);
+
+  int a

[llvm] [clang] [clang-tools-extra] [RFC] Perform lifetime bound checks for arguments to coroutine (PR #69360)

2023-11-10 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/69360

>From be3f5faa6cd17d76f26fb1bc6d6b59a8a78ffe82 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 17 Oct 2023 19:37:28 +0200
Subject: [PATCH 1/2] Lifetime bound check for coroutine

---
 clang/lib/Sema/SemaInit.cpp   |  16 +-
 .../SemaCXX/coroutine-lifetimebound-args.cpp  | 184 ++
 2 files changed, 198 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coroutine-lifetimebound-args.cpp

diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index fd95b16b84b6e3a..54e72b220bc47a4 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7607,11 +7607,23 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
 
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
-
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+for (const auto &attr :
+ RD->getUnderlyingDecl()->specific_attrs()) {
+  // Only for demonstration: Get feedback and add a clang annotation as an
+  // extension.
+  if (attr->getAnnotation() == "coro_type") {
+
+checkCoroCall = true;
+break;
+  }
+}
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/SemaCXX/coroutine-lifetimebound-args.cpp 
b/clang/test/SemaCXX/coroutine-lifetimebound-args.cpp
new file mode 100644
index 000..4cc5730ef896581
--- /dev/null
+++ b/clang/test/SemaCXX/coroutine-lifetimebound-args.cpp
@@ -0,0 +1,184 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+
+#define CORO_TYPE [[clang::annotate("coro_type")]]
+#define CORO_UNSAFE [[clang::annotate("coro_unsafe")]]
+
+template  struct CORO_TYPE Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept { return false; }
+void await_suspend(std::coroutine_handle<>) noexcept {}
+U await_resume() noexcept { return {}; }
+  };
+  return awaitable{};
+}
+  };
+};
+
+template  using Co = Gen;
+
+Gen foo_coro(const int& b);
+
+Gen plain_return_foo_decl(int b) {
+  return foo_coro(b); // expected-warning {{address of stack memory associated 
with parameter}}
+}
+
+Gen foo_coro(const int& b) {
+  if (b > 0)
+co_return 1;
+  co_return 2;
+}
+
+int getInt() { return 0; }
+
+Co bar_coro(const int &b, int c) {
+  int x = co_await foo_coro(b);
+  int y = co_await foo_coro(1);
+  int z = co_await foo_coro(getInt());
+  auto unsafe1 = foo_coro(1); // expected-warning {{temporary whose address is 
used as value of local variable}}
+  auto unsafe2 = foo_coro(getInt()); // expected-warning {{temporary whose 
address is used as value of local variable}}
+  auto  safe1 = foo_coro(b);
+  auto  safe2 = foo_coro(c);
+  co_return co_await foo_coro(co_await foo_coro(1));
+}
+
+Gen plain_return_co(int b) {
+  return foo_coro(b); // expected-warning {{address of stack memory associated 
with parameter}}
+}
+
+Gen safe_forwarding(const int& b) {
+  return foo_coro(b);
+}
+
+Gen unsafe_wrapper(int b) {
+  return safe_forwarding(b); // expected-warning {{address of stack memory 
associated with parameter}}
+}
+
+Co complex_plain_return(int b) {
+  return b > 0 
+  ? foo_coro(1)   // expected-warning {{returning address of local 
temporary object}}
+  : bar_coro(0, 1); // expected-warning {{returning address of local 
temporary object}}
+}
+
+void lambdas() {
+  auto unsafe_lambda = [](int b) {
+return foo_coro(b); // expected-warning {{address of stack memory 
associated with parameter}}
+  };
+  auto safe_lambda = [](int b) -> Co {
+int x = co_await foo_coro(1);
+co_return x + co_await foo_coro(b);
+  };
+}
+// 
=
+// Safe usage when parameters are value
+// 
=
+namespace by_value {
+Gen value_coro(int b) { co_return co_await foo_coro(b); }
+
+Gen wrapper1(int b) { return value_coro(b); }
+Gen wrapper2(const int& b) { return value_coro(b); }
+}
+
+// 
=
+// std::

[llvm] [clang] [clang-tools-extra] [RFC] Perform lifetime bound checks for arguments to coroutine (PR #69360)

2023-11-10 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/69360

>From be3f5faa6cd17d76f26fb1bc6d6b59a8a78ffe82 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 17 Oct 2023 19:37:28 +0200
Subject: [PATCH 1/3] Lifetime bound check for coroutine

---
 clang/lib/Sema/SemaInit.cpp   |  16 +-
 .../SemaCXX/coroutine-lifetimebound-args.cpp  | 184 ++
 2 files changed, 198 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coroutine-lifetimebound-args.cpp

diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index fd95b16b84b6e3a..54e72b220bc47a4 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7607,11 +7607,23 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
 
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
-
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+for (const auto &attr :
+ RD->getUnderlyingDecl()->specific_attrs()) {
+  // Only for demonstration: Get feedback and add a clang annotation as an
+  // extension.
+  if (attr->getAnnotation() == "coro_type") {
+
+checkCoroCall = true;
+break;
+  }
+}
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/SemaCXX/coroutine-lifetimebound-args.cpp 
b/clang/test/SemaCXX/coroutine-lifetimebound-args.cpp
new file mode 100644
index 000..4cc5730ef896581
--- /dev/null
+++ b/clang/test/SemaCXX/coroutine-lifetimebound-args.cpp
@@ -0,0 +1,184 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+
+#define CORO_TYPE [[clang::annotate("coro_type")]]
+#define CORO_UNSAFE [[clang::annotate("coro_unsafe")]]
+
+template  struct CORO_TYPE Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept { return false; }
+void await_suspend(std::coroutine_handle<>) noexcept {}
+U await_resume() noexcept { return {}; }
+  };
+  return awaitable{};
+}
+  };
+};
+
+template  using Co = Gen;
+
+Gen foo_coro(const int& b);
+
+Gen plain_return_foo_decl(int b) {
+  return foo_coro(b); // expected-warning {{address of stack memory associated 
with parameter}}
+}
+
+Gen foo_coro(const int& b) {
+  if (b > 0)
+co_return 1;
+  co_return 2;
+}
+
+int getInt() { return 0; }
+
+Co bar_coro(const int &b, int c) {
+  int x = co_await foo_coro(b);
+  int y = co_await foo_coro(1);
+  int z = co_await foo_coro(getInt());
+  auto unsafe1 = foo_coro(1); // expected-warning {{temporary whose address is 
used as value of local variable}}
+  auto unsafe2 = foo_coro(getInt()); // expected-warning {{temporary whose 
address is used as value of local variable}}
+  auto  safe1 = foo_coro(b);
+  auto  safe2 = foo_coro(c);
+  co_return co_await foo_coro(co_await foo_coro(1));
+}
+
+Gen plain_return_co(int b) {
+  return foo_coro(b); // expected-warning {{address of stack memory associated 
with parameter}}
+}
+
+Gen safe_forwarding(const int& b) {
+  return foo_coro(b);
+}
+
+Gen unsafe_wrapper(int b) {
+  return safe_forwarding(b); // expected-warning {{address of stack memory 
associated with parameter}}
+}
+
+Co complex_plain_return(int b) {
+  return b > 0 
+  ? foo_coro(1)   // expected-warning {{returning address of local 
temporary object}}
+  : bar_coro(0, 1); // expected-warning {{returning address of local 
temporary object}}
+}
+
+void lambdas() {
+  auto unsafe_lambda = [](int b) {
+return foo_coro(b); // expected-warning {{address of stack memory 
associated with parameter}}
+  };
+  auto safe_lambda = [](int b) -> Co {
+int x = co_await foo_coro(1);
+co_return x + co_await foo_coro(b);
+  };
+}
+// 
=
+// Safe usage when parameters are value
+// 
=
+namespace by_value {
+Gen value_coro(int b) { co_return co_await foo_coro(b); }
+
+Gen wrapper1(int b) { return value_coro(b); }
+Gen wrapper2(const int& b) { return value_coro(b); }
+}
+
+// 
=
+// std::

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-10 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 created https://github.com/llvm/llvm-project/pull/71945

First step in the implementation of 
[RFC](https://discourse.llvm.org/t/rfc-lifetime-bound-check-for-parameters-of-coroutines/74253)
 ([final proposal 
doc](https://docs.google.com/document/d/1hkfXHuvIW1Yv5LI-EIkpWzdWgIoUlzO6Zv_KJpknQzM/edit)).

This introduces the concepts of a coroutine return type and explicit coroutine 
wrapper functions. 

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName 

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-10 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 1/2] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl *

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-13 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 1/3] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl *

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-13 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 1/4] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl *

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-13 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-13 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 1/5] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl *

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-13 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Templated equals take 2 (PR #72213)

2023-11-13 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 created https://github.com/llvm/llvm-project/pull/72213

None

>From bc9e06ea87dca046227faf2996eb8de521863d57 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 20 Oct 2023 14:40:25 +0200
Subject: [PATCH 1/2] [clang] Handle templated operators with reversed
 arguments (#69595)

https://github.com/llvm/llvm-project/pull/68999 correctly computed
conversion sequence for reversed args to a template operators. This was
a breaking change as code, previously accepted in C++17, starts to break
in C++20.

Example:
```cpp
struct P {};
template bool operator==(const P&, const S &);

struct A : public P {};
struct B : public P {};
bool check(A a, B b) { return a == b; }  // This is now ambiguous in C++20.
```

In order to minimise widespread breakages, as a clang extension, we had
previously accepted such ambiguities with a warning
(`-Wambiguous-reversed-operator`) for non-template operators. Due to the
same reasons, we extend this relaxation for template operators.

Fixes https://github.com/llvm/llvm-project/issues/53954
---
 clang/docs/ReleaseNotes.rst   | 21 +++
 clang/lib/Sema/SemaOverload.cpp   | 28 ++---
 .../over.match.oper/p3-2a.cpp | 61 +++
 3 files changed, 100 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7a131cb520aa600..5c974eec9ed67d1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -37,6 +37,27 @@ These changes are ones which we think may surprise users 
when upgrading to
 Clang |release| because of the opportunity they pose for disruption to existing
 code bases.
 
+- Fix a bug in reversed argument for templated operators.
+  This breaks code in C++20 which was previously accepted in C++17. Eg:
+
+  .. code-block:: cpp
+
+struct P {};
+template bool operator==(const P&, const S&);
+
+struct A : public P {};
+struct B : public P {};
+
+// This equality is now ambiguous in C++20.
+bool ambiguous(A a, B b) { return a == b; }
+
+template bool operator!=(const P&, const S&);
+// Ok. Found a matching operator!=.
+bool fine(A a, B b) { return a == b; }
+
+  To reduce such widespread breakages, as an extension, Clang accepts this code
+  with an existing warning ``-Wambiguous-reversed-operator`` warning.
+  Fixes `GH `_.
 
 C/C++ Language Potentially Breaking Changes
 ---
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f97e244120612e3..73f417cc8bd4024 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7685,7 +7685,7 @@ bool Sema::CheckNonDependentConversions(
 QualType ParamType = ParamTypes[I + Offset];
 if (!ParamType->isDependentType()) {
   unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed
- ? 0
+ ? Args.size() - 1 - (ThisConversions + I)
  : (ThisConversions + I);
   Conversions[ConvIdx]
 = TryCopyInitialization(*this, Args[I], ParamType,
@@ -10082,11 +10082,19 @@ getImplicitObjectParamType(ASTContext &Context, const 
FunctionDecl *F) {
   return M->getFunctionObjectParameterReferenceType();
 }
 
-static bool haveSameParameterTypes(ASTContext &Context, const FunctionDecl *F1,
-   const FunctionDecl *F2) {
+// As a Clang extension, allow ambiguity among F1 and F2 if they represent
+// represent the same entity.
+static bool allowAmbiguity(ASTContext &Context, const FunctionDecl *F1,
+   const FunctionDecl *F2) {
   if (declaresSameEntity(F1, F2))
 return true;
-
+  if (F1->isTemplateInstantiation() && F2->isTemplateInstantiation() &&
+  declaresSameEntity(F1->getPrimaryTemplate(), F2->getPrimaryTemplate())) {
+return true;
+  }
+  // TODO: It is not clear whether comparing parameters is necessary (i.e.
+  // different functions with same params). Consider removing this (as no test
+  // fail w/o it).
   auto NextParam = [&](const FunctionDecl *F, unsigned &I, bool First) {
 if (First) {
   if (std::optional T = getImplicitObjectParamType(Context, F))
@@ -10271,14 +10279,14 @@ bool clang::isBetterOverloadCandidate(
 case ImplicitConversionSequence::Worse:
   if (Cand1.Function && Cand2.Function &&
   Cand1.isReversed() != Cand2.isReversed() &&
-  haveSameParameterTypes(S.Context, Cand1.Function, Cand2.Function)) {
+  allowAmbiguity(S.Context, Cand1.Function, Cand2.Function)) {
 // Work around large-scale breakage caused by considering reversed
 // forms of operator== in C++20:
 //
-// When comparing a function against a reversed function with the same
-// parameter types, if we have a better conversion for one argument and
-// a worse conversion for 

[clang] Templated equals take 2 (PR #72213)

2023-11-13 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Templated equals take 2 (PR #72213)

2023-11-13 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Templated equals take 2 (PR #72213)

2023-11-13 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Templated equals take 2 (PR #72213)

2023-11-13 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-14 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-14 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-14 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-14 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-14 Thread Utkarsh Saxena via cfe-commits


@@ -10088,9 +10088,13 @@ static bool allowAmbiguity(ASTContext &Context, const 
FunctionDecl *F1,
const FunctionDecl *F2) {
   if (declaresSameEntity(F1, F2))
 return true;
-  if (F1->isTemplateInstantiation() && F2->isTemplateInstantiation() &&
-  declaresSameEntity(F1->getPrimaryTemplate(), F2->getPrimaryTemplate())) {
-return true;
+  if (F1->isTemplateInstantiation() && F2->isTemplateInstantiation()) {
+auto PT1 = F1->getPrimaryTemplate();
+auto PT2 = F2->getPrimaryTemplate();
+if (declaresSameEntity(PT1, PT2) ||

usx95 wrote:

Fixed the crash. For some reason, the example is not ambiguous in any compiler 
https://godbolt.org/z/Gs34eo9cf. Trying to come up with a test case..

https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Add separate C++23 extension flag for attrs on lambda (PR #74553)

2023-12-05 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 created https://github.com/llvm/llvm-project/pull/74553

None

>From 9be87da42e48895cf23d90a3ed735b7a36b1ccb3 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 6 Dec 2023 04:51:45 +0100
Subject: [PATCH] [clang] Add separate C++23 extension flag for attrs on lambda

---
 clang/include/clang/Basic/DiagnosticGroups.td   |  4 +++-
 clang/include/clang/Basic/DiagnosticParseKinds.td   |  2 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp   | 10 ++
 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp |  9 ++---
 4 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index ff028bbbf7426..81443fb16a1f3 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1126,6 +1126,8 @@ def FutureAttrs : 
DiagGroup<"future-attribute-extensions", [CXX14Attrs,
 CXX17Attrs,
 CXX20Attrs]>;
 
+def CXX23AttrsOnLambda : DiagGroup<"c++23-attrs-on-lambda">;
+
 // A warning group for warnings about using C++11 features as extensions in
 // earlier C++ versions.
 def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, 
CXX11InlineNamespace,
@@ -1145,7 +1147,7 @@ def CXX20 : DiagGroup<"c++20-extensions", 
[CXX20Designator, CXX20Attrs]>;
 
 // A warning group for warnings about using C++23 features as extensions in
 // earlier C++ versions.
-def CXX23 : DiagGroup<"c++23-extensions">;
+def CXX23 : DiagGroup<"c++23-extensions", [CXX23AttrsOnLambda]>;
 
 // A warning group for warnings about using C++26 features as extensions in
 // earlier C++ versions.
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 21fe6066d5876..bc7bd7589ef14 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1035,7 +1035,7 @@ def err_capture_default_first : Error<
   "capture default must be first">;
 def ext_decl_attrs_on_lambda : ExtWarn<
   "%select{an attribute specifier sequence|%0}1 in this position "
-  "is a C++23 extension">, InGroup;
+  "is a C++23 extension">, InGroup;
 def ext_lambda_missing_parens : ExtWarn<
   "lambda without a parameter clause is a C++23 extension">,
   InGroup;
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
index d3e2d673ebb3c..ec8997036feb4 100644
--- a/clang/test/SemaCXX/coro-lifetimebound.cpp
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused 
-Wno-c++23-attrs-on-lambda
 
 #include "Inputs/std-coroutine.h"
 
@@ -64,14 +64,8 @@ Co bar_coro(const int &b, int c) {
   : bar_coro(0, 1); // expected-warning {{returning address of local 
temporary object}}
 }
 
-#define CORO_WRAPPER \
-  _Pragma("clang diagnostic push") \
-  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
-  [[clang::coro_wrapper]] \
-  _Pragma("clang diagnostic pop")
-
 void lambdas() {
-  auto unsafe_lambda = [] CORO_WRAPPER (int b) {
+  auto unsafe_lambda = [] [[clang::coro_wrapper]] (int b) {
 return foo_coro(b); // expected-warning {{address of stack memory 
associated with parameter}}
   };
   auto coro_lambda = [] (const int&) -> Co {
diff --git a/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp 
b/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
index 5f8076f1c782a..d52d1e4cea399 100644
--- a/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
+++ b/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-c++23-attrs-on-lambda
 #include "Inputs/std-coroutine.h"
 
 using std::suspend_always;
@@ -45,11 +45,6 @@ Co non_marked_wrapper(int b) { return foo_coro(b); }
 } // namespace using_decl
 
 namespace lambdas {
-#define CORO_WRAPPER \
-  _Pragma("clang diagnostic push") \
-  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
-  [[clang::coro_wrapper]] \
-  _Pragma("clang diagnostic pop")
 
 void foo() {
   auto coro_lambda = []() -> Gen {
@@ -59,7 +54,7 @@ void foo() {
   auto not_allowed_wrapper = []() -> Gen {
 return foo_coro(1);
   };
-  auto allowed_wrapper = [] CORO_WRAPPER() -> Gen {
+  auto allowed_wrapper = [] [[clang::coro_wrapper]] () -> Gen {
 return foo_coro(1);
   };
 }

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists

[clang] [clang] Add separate C++23 extension flag for attrs on lambda (PR #74553)

2023-12-05 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/74553

>From 9be87da42e48895cf23d90a3ed735b7a36b1ccb3 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 6 Dec 2023 04:51:45 +0100
Subject: [PATCH 1/2] [clang] Add separate C++23 extension flag for attrs on
 lambda

---
 clang/include/clang/Basic/DiagnosticGroups.td   |  4 +++-
 clang/include/clang/Basic/DiagnosticParseKinds.td   |  2 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp   | 10 ++
 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp |  9 ++---
 4 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index ff028bbbf7426..81443fb16a1f3 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1126,6 +1126,8 @@ def FutureAttrs : 
DiagGroup<"future-attribute-extensions", [CXX14Attrs,
 CXX17Attrs,
 CXX20Attrs]>;
 
+def CXX23AttrsOnLambda : DiagGroup<"c++23-attrs-on-lambda">;
+
 // A warning group for warnings about using C++11 features as extensions in
 // earlier C++ versions.
 def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, 
CXX11InlineNamespace,
@@ -1145,7 +1147,7 @@ def CXX20 : DiagGroup<"c++20-extensions", 
[CXX20Designator, CXX20Attrs]>;
 
 // A warning group for warnings about using C++23 features as extensions in
 // earlier C++ versions.
-def CXX23 : DiagGroup<"c++23-extensions">;
+def CXX23 : DiagGroup<"c++23-extensions", [CXX23AttrsOnLambda]>;
 
 // A warning group for warnings about using C++26 features as extensions in
 // earlier C++ versions.
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 21fe6066d5876..bc7bd7589ef14 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1035,7 +1035,7 @@ def err_capture_default_first : Error<
   "capture default must be first">;
 def ext_decl_attrs_on_lambda : ExtWarn<
   "%select{an attribute specifier sequence|%0}1 in this position "
-  "is a C++23 extension">, InGroup;
+  "is a C++23 extension">, InGroup;
 def ext_lambda_missing_parens : ExtWarn<
   "lambda without a parameter clause is a C++23 extension">,
   InGroup;
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
index d3e2d673ebb3c..ec8997036feb4 100644
--- a/clang/test/SemaCXX/coro-lifetimebound.cpp
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused 
-Wno-c++23-attrs-on-lambda
 
 #include "Inputs/std-coroutine.h"
 
@@ -64,14 +64,8 @@ Co bar_coro(const int &b, int c) {
   : bar_coro(0, 1); // expected-warning {{returning address of local 
temporary object}}
 }
 
-#define CORO_WRAPPER \
-  _Pragma("clang diagnostic push") \
-  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
-  [[clang::coro_wrapper]] \
-  _Pragma("clang diagnostic pop")
-
 void lambdas() {
-  auto unsafe_lambda = [] CORO_WRAPPER (int b) {
+  auto unsafe_lambda = [] [[clang::coro_wrapper]] (int b) {
 return foo_coro(b); // expected-warning {{address of stack memory 
associated with parameter}}
   };
   auto coro_lambda = [] (const int&) -> Co {
diff --git a/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp 
b/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
index 5f8076f1c782a..d52d1e4cea399 100644
--- a/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
+++ b/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-c++23-attrs-on-lambda
 #include "Inputs/std-coroutine.h"
 
 using std::suspend_always;
@@ -45,11 +45,6 @@ Co non_marked_wrapper(int b) { return foo_coro(b); }
 } // namespace using_decl
 
 namespace lambdas {
-#define CORO_WRAPPER \
-  _Pragma("clang diagnostic push") \
-  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
-  [[clang::coro_wrapper]] \
-  _Pragma("clang diagnostic pop")
 
 void foo() {
   auto coro_lambda = []() -> Gen {
@@ -59,7 +54,7 @@ void foo() {
   auto not_allowed_wrapper = []() -> Gen {
 return foo_coro(1);
   };
-  auto allowed_wrapper = [] CORO_WRAPPER() -> Gen {
+  auto allowed_wrapper = [] [[clang::coro_wrapper]] () -> Gen {
 return foo_coro(1);
   };
 }

>From 14532988c00fc0ce6530a05a899abbc3976bd374 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 6 Dec 202

[clang] [clang] Add separate C++23 extension flag for attrs on lambda (PR #74553)

2023-12-06 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/74553

>From 9be87da42e48895cf23d90a3ed735b7a36b1ccb3 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 6 Dec 2023 04:51:45 +0100
Subject: [PATCH 1/3] [clang] Add separate C++23 extension flag for attrs on
 lambda

---
 clang/include/clang/Basic/DiagnosticGroups.td   |  4 +++-
 clang/include/clang/Basic/DiagnosticParseKinds.td   |  2 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp   | 10 ++
 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp |  9 ++---
 4 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index ff028bbbf7426..81443fb16a1f3 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1126,6 +1126,8 @@ def FutureAttrs : 
DiagGroup<"future-attribute-extensions", [CXX14Attrs,
 CXX17Attrs,
 CXX20Attrs]>;
 
+def CXX23AttrsOnLambda : DiagGroup<"c++23-attrs-on-lambda">;
+
 // A warning group for warnings about using C++11 features as extensions in
 // earlier C++ versions.
 def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, 
CXX11InlineNamespace,
@@ -1145,7 +1147,7 @@ def CXX20 : DiagGroup<"c++20-extensions", 
[CXX20Designator, CXX20Attrs]>;
 
 // A warning group for warnings about using C++23 features as extensions in
 // earlier C++ versions.
-def CXX23 : DiagGroup<"c++23-extensions">;
+def CXX23 : DiagGroup<"c++23-extensions", [CXX23AttrsOnLambda]>;
 
 // A warning group for warnings about using C++26 features as extensions in
 // earlier C++ versions.
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 21fe6066d5876..bc7bd7589ef14 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1035,7 +1035,7 @@ def err_capture_default_first : Error<
   "capture default must be first">;
 def ext_decl_attrs_on_lambda : ExtWarn<
   "%select{an attribute specifier sequence|%0}1 in this position "
-  "is a C++23 extension">, InGroup;
+  "is a C++23 extension">, InGroup;
 def ext_lambda_missing_parens : ExtWarn<
   "lambda without a parameter clause is a C++23 extension">,
   InGroup;
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
index d3e2d673ebb3c..ec8997036feb4 100644
--- a/clang/test/SemaCXX/coro-lifetimebound.cpp
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused 
-Wno-c++23-attrs-on-lambda
 
 #include "Inputs/std-coroutine.h"
 
@@ -64,14 +64,8 @@ Co bar_coro(const int &b, int c) {
   : bar_coro(0, 1); // expected-warning {{returning address of local 
temporary object}}
 }
 
-#define CORO_WRAPPER \
-  _Pragma("clang diagnostic push") \
-  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
-  [[clang::coro_wrapper]] \
-  _Pragma("clang diagnostic pop")
-
 void lambdas() {
-  auto unsafe_lambda = [] CORO_WRAPPER (int b) {
+  auto unsafe_lambda = [] [[clang::coro_wrapper]] (int b) {
 return foo_coro(b); // expected-warning {{address of stack memory 
associated with parameter}}
   };
   auto coro_lambda = [] (const int&) -> Co {
diff --git a/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp 
b/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
index 5f8076f1c782a..d52d1e4cea399 100644
--- a/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
+++ b/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-c++23-attrs-on-lambda
 #include "Inputs/std-coroutine.h"
 
 using std::suspend_always;
@@ -45,11 +45,6 @@ Co non_marked_wrapper(int b) { return foo_coro(b); }
 } // namespace using_decl
 
 namespace lambdas {
-#define CORO_WRAPPER \
-  _Pragma("clang diagnostic push") \
-  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
-  [[clang::coro_wrapper]] \
-  _Pragma("clang diagnostic pop")
 
 void foo() {
   auto coro_lambda = []() -> Gen {
@@ -59,7 +54,7 @@ void foo() {
   auto not_allowed_wrapper = []() -> Gen {
 return foo_coro(1);
   };
-  auto allowed_wrapper = [] CORO_WRAPPER() -> Gen {
+  auto allowed_wrapper = [] [[clang::coro_wrapper]] () -> Gen {
 return foo_coro(1);
   };
 }

>From 14532988c00fc0ce6530a05a899abbc3976bd374 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 6 Dec 202

[clang] [clang] Add separate C++23 extension flag for attrs on lambda (PR #74553)

2023-12-06 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/74553

>From 9be87da42e48895cf23d90a3ed735b7a36b1ccb3 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 6 Dec 2023 04:51:45 +0100
Subject: [PATCH 1/4] [clang] Add separate C++23 extension flag for attrs on
 lambda

---
 clang/include/clang/Basic/DiagnosticGroups.td   |  4 +++-
 clang/include/clang/Basic/DiagnosticParseKinds.td   |  2 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp   | 10 ++
 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp |  9 ++---
 4 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index ff028bbbf7426..81443fb16a1f3 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1126,6 +1126,8 @@ def FutureAttrs : 
DiagGroup<"future-attribute-extensions", [CXX14Attrs,
 CXX17Attrs,
 CXX20Attrs]>;
 
+def CXX23AttrsOnLambda : DiagGroup<"c++23-attrs-on-lambda">;
+
 // A warning group for warnings about using C++11 features as extensions in
 // earlier C++ versions.
 def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, 
CXX11InlineNamespace,
@@ -1145,7 +1147,7 @@ def CXX20 : DiagGroup<"c++20-extensions", 
[CXX20Designator, CXX20Attrs]>;
 
 // A warning group for warnings about using C++23 features as extensions in
 // earlier C++ versions.
-def CXX23 : DiagGroup<"c++23-extensions">;
+def CXX23 : DiagGroup<"c++23-extensions", [CXX23AttrsOnLambda]>;
 
 // A warning group for warnings about using C++26 features as extensions in
 // earlier C++ versions.
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 21fe6066d5876..bc7bd7589ef14 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1035,7 +1035,7 @@ def err_capture_default_first : Error<
   "capture default must be first">;
 def ext_decl_attrs_on_lambda : ExtWarn<
   "%select{an attribute specifier sequence|%0}1 in this position "
-  "is a C++23 extension">, InGroup;
+  "is a C++23 extension">, InGroup;
 def ext_lambda_missing_parens : ExtWarn<
   "lambda without a parameter clause is a C++23 extension">,
   InGroup;
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
index d3e2d673ebb3c..ec8997036feb4 100644
--- a/clang/test/SemaCXX/coro-lifetimebound.cpp
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused 
-Wno-c++23-attrs-on-lambda
 
 #include "Inputs/std-coroutine.h"
 
@@ -64,14 +64,8 @@ Co bar_coro(const int &b, int c) {
   : bar_coro(0, 1); // expected-warning {{returning address of local 
temporary object}}
 }
 
-#define CORO_WRAPPER \
-  _Pragma("clang diagnostic push") \
-  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
-  [[clang::coro_wrapper]] \
-  _Pragma("clang diagnostic pop")
-
 void lambdas() {
-  auto unsafe_lambda = [] CORO_WRAPPER (int b) {
+  auto unsafe_lambda = [] [[clang::coro_wrapper]] (int b) {
 return foo_coro(b); // expected-warning {{address of stack memory 
associated with parameter}}
   };
   auto coro_lambda = [] (const int&) -> Co {
diff --git a/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp 
b/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
index 5f8076f1c782a..d52d1e4cea399 100644
--- a/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
+++ b/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-c++23-attrs-on-lambda
 #include "Inputs/std-coroutine.h"
 
 using std::suspend_always;
@@ -45,11 +45,6 @@ Co non_marked_wrapper(int b) { return foo_coro(b); }
 } // namespace using_decl
 
 namespace lambdas {
-#define CORO_WRAPPER \
-  _Pragma("clang diagnostic push") \
-  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
-  [[clang::coro_wrapper]] \
-  _Pragma("clang diagnostic pop")
 
 void foo() {
   auto coro_lambda = []() -> Gen {
@@ -59,7 +54,7 @@ void foo() {
   auto not_allowed_wrapper = []() -> Gen {
 return foo_coro(1);
   };
-  auto allowed_wrapper = [] CORO_WRAPPER() -> Gen {
+  auto allowed_wrapper = [] [[clang::coro_wrapper]] () -> Gen {
 return foo_coro(1);
   };
 }

>From 14532988c00fc0ce6530a05a899abbc3976bd374 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 6 Dec 202

[clang] [clang] Add separate C++23 extension flag for attrs on lambda (PR #74553)

2023-12-07 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 closed https://github.com/llvm/llvm-project/pull/74553
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-14 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72213

>From bc9e06ea87dca046227faf2996eb8de521863d57 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 20 Oct 2023 14:40:25 +0200
Subject: [PATCH 1/3] [clang] Handle templated operators with reversed
 arguments (#69595)

https://github.com/llvm/llvm-project/pull/68999 correctly computed
conversion sequence for reversed args to a template operators. This was
a breaking change as code, previously accepted in C++17, starts to break
in C++20.

Example:
```cpp
struct P {};
template bool operator==(const P&, const S &);

struct A : public P {};
struct B : public P {};
bool check(A a, B b) { return a == b; }  // This is now ambiguous in C++20.
```

In order to minimise widespread breakages, as a clang extension, we had
previously accepted such ambiguities with a warning
(`-Wambiguous-reversed-operator`) for non-template operators. Due to the
same reasons, we extend this relaxation for template operators.

Fixes https://github.com/llvm/llvm-project/issues/53954
---
 clang/docs/ReleaseNotes.rst   | 21 +++
 clang/lib/Sema/SemaOverload.cpp   | 28 ++---
 .../over.match.oper/p3-2a.cpp | 61 +++
 3 files changed, 100 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7a131cb520aa600..5c974eec9ed67d1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -37,6 +37,27 @@ These changes are ones which we think may surprise users 
when upgrading to
 Clang |release| because of the opportunity they pose for disruption to existing
 code bases.
 
+- Fix a bug in reversed argument for templated operators.
+  This breaks code in C++20 which was previously accepted in C++17. Eg:
+
+  .. code-block:: cpp
+
+struct P {};
+template bool operator==(const P&, const S&);
+
+struct A : public P {};
+struct B : public P {};
+
+// This equality is now ambiguous in C++20.
+bool ambiguous(A a, B b) { return a == b; }
+
+template bool operator!=(const P&, const S&);
+// Ok. Found a matching operator!=.
+bool fine(A a, B b) { return a == b; }
+
+  To reduce such widespread breakages, as an extension, Clang accepts this code
+  with an existing warning ``-Wambiguous-reversed-operator`` warning.
+  Fixes `GH `_.
 
 C/C++ Language Potentially Breaking Changes
 ---
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f97e244120612e3..73f417cc8bd4024 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7685,7 +7685,7 @@ bool Sema::CheckNonDependentConversions(
 QualType ParamType = ParamTypes[I + Offset];
 if (!ParamType->isDependentType()) {
   unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed
- ? 0
+ ? Args.size() - 1 - (ThisConversions + I)
  : (ThisConversions + I);
   Conversions[ConvIdx]
 = TryCopyInitialization(*this, Args[I], ParamType,
@@ -10082,11 +10082,19 @@ getImplicitObjectParamType(ASTContext &Context, const 
FunctionDecl *F) {
   return M->getFunctionObjectParameterReferenceType();
 }
 
-static bool haveSameParameterTypes(ASTContext &Context, const FunctionDecl *F1,
-   const FunctionDecl *F2) {
+// As a Clang extension, allow ambiguity among F1 and F2 if they represent
+// represent the same entity.
+static bool allowAmbiguity(ASTContext &Context, const FunctionDecl *F1,
+   const FunctionDecl *F2) {
   if (declaresSameEntity(F1, F2))
 return true;
-
+  if (F1->isTemplateInstantiation() && F2->isTemplateInstantiation() &&
+  declaresSameEntity(F1->getPrimaryTemplate(), F2->getPrimaryTemplate())) {
+return true;
+  }
+  // TODO: It is not clear whether comparing parameters is necessary (i.e.
+  // different functions with same params). Consider removing this (as no test
+  // fail w/o it).
   auto NextParam = [&](const FunctionDecl *F, unsigned &I, bool First) {
 if (First) {
   if (std::optional T = getImplicitObjectParamType(Context, F))
@@ -10271,14 +10279,14 @@ bool clang::isBetterOverloadCandidate(
 case ImplicitConversionSequence::Worse:
   if (Cand1.Function && Cand2.Function &&
   Cand1.isReversed() != Cand2.isReversed() &&
-  haveSameParameterTypes(S.Context, Cand1.Function, Cand2.Function)) {
+  allowAmbiguity(S.Context, Cand1.Function, Cand2.Function)) {
 // Work around large-scale breakage caused by considering reversed
 // forms of operator== in C++20:
 //
-// When comparing a function against a reversed function with the same
-// parameter types, if we have a better conversion for one argument and
-// a worse conversion for the ot

[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-14 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

I ran this change internally and noticed a crash for 
```cpp
template 
class Foo {
 public:
  template 
  bool operator==(const Foo& other) const;
};

bool x = Foo{} == Foo{};
```

stacktrace

```
F 00:00:1700029943.3152478971 logging.cc:57] assert.h assertion failed 
at third_party/llvm/llvm-project/llvm/include/llvm/ADT/ArrayRef.h:443 in T 
&llvm::MutableArrayRef::operator[](size_t) 
const [T = clang::ImplicitConversionSequence]: Index < this->size() && "Invalid 
index!"
*** Check failure stack trace: ***
@ 0x55598a5f6a44  absl::log_internal::LogMessage::SendToLog()
@ 0x55598a5f68a2  absl::log_internal::LogMessage::Flush()
@ 0x55598a5f6da9  
absl::log_internal::LogMessageFatal::~LogMessageFatal()
@ 0x55598a5e70c4  __assert_fail
@ 0x555986a73209  clang::Sema::CheckNonDependentConversions()
@ 0x555986a9db52  llvm::function_ref<>::callback_fn<>()
@ 0x555986c6bc08  llvm::function_ref<>::callback_fn<>()
@ 0x555986bf70b3  clang::Sema::FinishTemplateArgumentDeduction()
@ 0x555986c6bb56  llvm::function_ref<>::callback_fn<>()
@ 0x5559862dbc2f  clang::Sema::runWithSufficientStackSpace()
@ 0x555986bf8f8d  clang::Sema::DeduceTemplateArguments()
@ 0x555986a7229a  clang::Sema::AddMethodTemplateCandidate()
@ 0x555986a72c6f  clang::Sema::AddMethodCandidate()
@ 0x555986a751dd  clang::Sema::AddMemberOperatorCandidates()
@ 0x555986a881f6  clang::Sema::LookupOverloadedBinOp()
@ 0x555986a88673  clang::Sema::CreateOverloadedBinOp()
@ 0x5559866ff91a  BuildOverloadedBinOp()
@ 0x5559866c643e  clang::Sema::ActOnBinOp()
@ 0x555986050faf  clang::Parser::ParseRHSOfBinaryExpression()
@ 0x55598604fcac  clang::Parser::ParseAssignmentExpression()
@ 0x555
```



https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-14 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72213

>From bc9e06ea87dca046227faf2996eb8de521863d57 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 20 Oct 2023 14:40:25 +0200
Subject: [PATCH 1/4] [clang] Handle templated operators with reversed
 arguments (#69595)

https://github.com/llvm/llvm-project/pull/68999 correctly computed
conversion sequence for reversed args to a template operators. This was
a breaking change as code, previously accepted in C++17, starts to break
in C++20.

Example:
```cpp
struct P {};
template bool operator==(const P&, const S &);

struct A : public P {};
struct B : public P {};
bool check(A a, B b) { return a == b; }  // This is now ambiguous in C++20.
```

In order to minimise widespread breakages, as a clang extension, we had
previously accepted such ambiguities with a warning
(`-Wambiguous-reversed-operator`) for non-template operators. Due to the
same reasons, we extend this relaxation for template operators.

Fixes https://github.com/llvm/llvm-project/issues/53954
---
 clang/docs/ReleaseNotes.rst   | 21 +++
 clang/lib/Sema/SemaOverload.cpp   | 28 ++---
 .../over.match.oper/p3-2a.cpp | 61 +++
 3 files changed, 100 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7a131cb520aa600..5c974eec9ed67d1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -37,6 +37,27 @@ These changes are ones which we think may surprise users 
when upgrading to
 Clang |release| because of the opportunity they pose for disruption to existing
 code bases.
 
+- Fix a bug in reversed argument for templated operators.
+  This breaks code in C++20 which was previously accepted in C++17. Eg:
+
+  .. code-block:: cpp
+
+struct P {};
+template bool operator==(const P&, const S&);
+
+struct A : public P {};
+struct B : public P {};
+
+// This equality is now ambiguous in C++20.
+bool ambiguous(A a, B b) { return a == b; }
+
+template bool operator!=(const P&, const S&);
+// Ok. Found a matching operator!=.
+bool fine(A a, B b) { return a == b; }
+
+  To reduce such widespread breakages, as an extension, Clang accepts this code
+  with an existing warning ``-Wambiguous-reversed-operator`` warning.
+  Fixes `GH `_.
 
 C/C++ Language Potentially Breaking Changes
 ---
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f97e244120612e3..73f417cc8bd4024 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7685,7 +7685,7 @@ bool Sema::CheckNonDependentConversions(
 QualType ParamType = ParamTypes[I + Offset];
 if (!ParamType->isDependentType()) {
   unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed
- ? 0
+ ? Args.size() - 1 - (ThisConversions + I)
  : (ThisConversions + I);
   Conversions[ConvIdx]
 = TryCopyInitialization(*this, Args[I], ParamType,
@@ -10082,11 +10082,19 @@ getImplicitObjectParamType(ASTContext &Context, const 
FunctionDecl *F) {
   return M->getFunctionObjectParameterReferenceType();
 }
 
-static bool haveSameParameterTypes(ASTContext &Context, const FunctionDecl *F1,
-   const FunctionDecl *F2) {
+// As a Clang extension, allow ambiguity among F1 and F2 if they represent
+// represent the same entity.
+static bool allowAmbiguity(ASTContext &Context, const FunctionDecl *F1,
+   const FunctionDecl *F2) {
   if (declaresSameEntity(F1, F2))
 return true;
-
+  if (F1->isTemplateInstantiation() && F2->isTemplateInstantiation() &&
+  declaresSameEntity(F1->getPrimaryTemplate(), F2->getPrimaryTemplate())) {
+return true;
+  }
+  // TODO: It is not clear whether comparing parameters is necessary (i.e.
+  // different functions with same params). Consider removing this (as no test
+  // fail w/o it).
   auto NextParam = [&](const FunctionDecl *F, unsigned &I, bool First) {
 if (First) {
   if (std::optional T = getImplicitObjectParamType(Context, F))
@@ -10271,14 +10279,14 @@ bool clang::isBetterOverloadCandidate(
 case ImplicitConversionSequence::Worse:
   if (Cand1.Function && Cand2.Function &&
   Cand1.isReversed() != Cand2.isReversed() &&
-  haveSameParameterTypes(S.Context, Cand1.Function, Cand2.Function)) {
+  allowAmbiguity(S.Context, Cand1.Function, Cand2.Function)) {
 // Work around large-scale breakage caused by considering reversed
 // forms of operator== in C++20:
 //
-// When comparing a function against a reversed function with the same
-// parameter types, if we have a better conversion for one argument and
-// a worse conversion for the ot

[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-15 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-15 Thread Utkarsh Saxena via cfe-commits


@@ -15811,6 +15813,32 @@ static void diagnoseImplicitlyRetainedSelf(Sema &S) {
   << FixItHint::CreateInsertion(P.first, "self->");
 }
 
+// Return whether FD is `promise_type::get_return_object`.
+bool isGetReturnObject(FunctionDecl *FD) {
+  if (!FD->getDeclName().isIdentifier() ||
+  !FD->getName().equals("get_return_object") || !FD->param_empty())
+return false;
+  CXXMethodDecl *MD = dyn_cast(FD);
+  if (!MD || !MD->isCXXInstanceMember())
+return false;
+  RecordDecl *PromiseType = MD->getParent();
+  return PromiseType && PromiseType->getDeclName().isIdentifier() &&

usx95 wrote:

Don't know what was I thinking. Thanks.

https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-15 Thread Utkarsh Saxena via cfe-commits


@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "

usx95 wrote:

Added [[clang::coro_return_type]] to the error message.

https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-15 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 1/6] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl *

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-15 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 1/8] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl *

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-15 Thread Utkarsh Saxena via cfe-commits


@@ -7482,3 +7482,54 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The ``coro_return_type`` attribute should be marked on a C++ class to mark it 
as

usx95 wrote:

Fixed in another suggestion. Thanks.

https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-16 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 1/9] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl *

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72516)

2023-11-16 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 converted_to_draft 
https://github.com/llvm/llvm-project/pull/72516
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72516)

2023-11-16 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 created https://github.com/llvm/llvm-project/pull/72516

None

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 1/9] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   Var

[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-17 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

This PR is not related to [cwg2804](https://wg21.link/cwg2804). We are already 
aware of the mentioned issue and are tracking it in 
https://github.com/llvm/llvm-project/issues/70210.

This PR is different and it fixes an implementation bug in rewriting template 
non-member operators (the conversion seq was computed incorrectly and 
associated to incorrect index). The difference in compilers 
([godbolt](https://godbolt.org/z/11331KW6e)) you currently see is because of 
this bug and clang would also correctly consider the example as ambiguous.

https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Reapply Handle templated operators with reversed arguments (PR #72213)

2023-11-17 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

I wanted to note down the challenges of landing this and the strategy to move 
forward.

 Challenges
* Landing this would make old code ambiguous 
([example](https://godbolt.org/z/11331KW6e)). This is not unexpected, and it is 
ambiguous in C++20.
* This would break LLVM in C++20 
([breakage](https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/ADT/STLExtras.h#L1293-L1303)).
 We do not want to break LLVM at head.
* But it would not be possible to resolve ambiguity also for **template friend 
functions** because of 
[cwg2804](https://cplusplus.github.io/CWG/issues/2804.html).
* In order to resolve this ambiguity, one solution is to make the operator 
non-friend and add a matching `operator!=` 
([P2468R2](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2468r2.html)).
 This is done in https://github.com/llvm/llvm-project/pull/72348. The solution 
would look like:
  ```cpp
  namespace N{
  struct P {};
  template bool operator==(const P&, const S &);
  template bool operator!=(const P&, const S &);
  struct A : public P {};
  struct B : public P {};
  }
  bool x = N::A{} == N::B{};
  ```
* The catch is that clang only recently fixed its  
([P2468R2](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2468r2.html))
 implementation for `operators==` found through ADL in 
https://github.com/llvm/llvm-project/commit/9330261143ccbe947ef0687fd20747ba47f26879.
* Without the above fix, LLVM would still be broken in clang-17 (because 
clang-17 doesn't have 
https://github.com/llvm/llvm-project/commit/9330261143ccbe947ef0687fd20747ba47f26879).

 Strategy
1. Wait for cherrypicking 
https://github.com/llvm/llvm-project-release-prs/pull/778 into clang-17.0.6.
2. Land https://github.com/llvm/llvm-project/pull/72348 to unbreak LLVM.
3. Update the latest revision to build LLVM in C++20 to **17.0.6**.
4. Land this PR https://github.com/llvm/llvm-project/pull/72213 
5. Implement [cwg2804](https://cplusplus.github.io/CWG/issues/2804.html) 
proposal when finalised.
6. **clang-18** would have correct behaviour for template operators, i.e., 
correct ambiguities surfaced with the option of resolving through adding 
matching `operator!=`.


https://github.com/llvm/llvm-project/pull/72213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits


@@ -15811,6 +15813,20 @@ static void diagnoseImplicitlyRetainedSelf(Sema &S) {
   << FixItHint::CreateInsertion(P.first, "self->");
 }
 
+void Sema::CheckCoroutineWrapper(FunctionDecl *FD) {
+  if (!FD || getCurFunction()->isCoroutine())

usx95 wrote:

`getCurFunction()` returns the function scope info which contains information 
about the processed function body being a coroutine or not. FD and 
getCurFunction() refers to the same function (one is decl and the other is FSI).

I will add a lambda inside a coroutine test to clarify.

https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits


@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+
+template  struct [[clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept { return false; }
+void await_suspend(std::coroutine_handle<>) noexcept {}
+U await_resume() noexcept { return {}; }
+  };
+  return awaitable{};
+}
+  };
+};
+
+Gen foo_coro(int b);
+Gen foo_coro(int b) { co_return b; }
+
+[[clang::coro_wrapper]] Gen marked_wrapper1(int b) { return foo_coro(b); }
+
+// expected-error@+1 {{neither a coroutine nor a coroutine wrapper}}
+Gen non_marked_wrapper(int b) { return foo_coro(b); }
+
+namespace using_decl {
+template  using Co = Gen;
+
+[[clang::coro_wrapper]] Co marked_wrapper1(int b) { return foo_coro(b); }
+
+// expected-error@+1 {{neither a coroutine nor a coroutine wrapper}}
+Co non_marked_wrapper(int b) { return foo_coro(b); }
+} // namespace using_decl
+
+namespace lambdas {
+void foo() {
+  auto coro_lambda = []() -> Gen {
+co_return 1;
+  };
+  // expected-error@+1 {{neither a coroutine nor a coroutine wrapper}}
+  auto wrapper_lambda = []() -> Gen {

usx95 wrote:

Missed to add this test.  This would be ugly, although possible, if we silenced 
the C++23 extension warning 🥲
```cpp
#define CORO_WRAPPER \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
  [[clang::coro_wrapper]] \
  _Pragma("clang diagnostic pop")

void foo() {
  auto allowed_wrapper = [] CORO_WRAPPER() -> Gen {
return some_coroutine(1);
  };
}
```

Added the test.

https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 01/11] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 01/12] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits


@@ -15811,6 +15813,20 @@ static void diagnoseImplicitlyRetainedSelf(Sema &S) {
   << FixItHint::CreateInsertion(P.first, "self->");
 }
 
+void Sema::CheckCoroutineWrapper(FunctionDecl *FD) {
+  if (!FD || getCurFunction()->isCoroutine())

usx95 wrote:

Moved `getCurFunction()` out and updated docs to say that it expects FD to be 
non-coroutine.

https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits


@@ -300,6 +300,11 @@ Attribute Changes in Clang
   to reduce the size of the destroy functions for coroutines which are known to
   be destroyed after having reached the final suspend point.
 
+- Clang now introduced ``[[clang::coro_return_type]]`` and 
``[[clang::coro_wrapper]]``
+  attributes. A function returning a type marked with 
``[[clang::coro_return_type]]``
+  should be a coroutine. A non-coroutine function marked with 
``[[clang::coro_wrapper]]``

usx95 wrote:

acknowledged.

https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 01/13] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

Thank you everyone for the review.

https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/71945

>From 89a2d60fc012742a74a008fb77213bcd47734503 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 10 Nov 2023 15:10:44 +0100
Subject: [PATCH 01/14] [coroutines] Introduce [[clang::coro_return_type]] and
 [[clang::co ro_wrapper]]

---
 clang/include/clang/Basic/Attr.td | 16 +
 clang/include/clang/Basic/AttrDocs.td | 67 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/include/clang/Sema/Sema.h   |  1 +
 clang/lib/Sema/SemaDecl.cpp   | 25 ++-
 ...a-attribute-supported-attributes-list.test |  2 +
 .../SemaCXX/coro-return-type-and-wrapper.cpp  | 56 
 7 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-return-type-and-wrapper.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31434565becaec6..f7a2b83b15ef5bc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1094,6 +1094,22 @@ def CoroOnlyDestroyWhenComplete : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroReturnType : InheritableAttr {
+  let Spellings = [Clang<"coro_return_type">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+  let Spellings = [Clang<"coro_wrapper">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroReturnTypeAndWrapperDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fa6f6acd0c30e88..66c92bcaa2d4a4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7482,3 +7482,70 @@ generation of the other destruction cases, optimizing 
the above `foo.destroy` to
 
   }];
 }
+
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ 
class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed 
only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function 
for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+  A foo() {
+dtor d;
+co_await something();
+dtor d1;
+co_await something();
+dtor d2;
+co_return 43;
+  }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+switch(frame->suspend_index()) {
+  case 1:
+frame->d.~dtor();
+break;
+  case 2:
+frame->d.~dtor();
+frame->d1.~dtor();
+break;
+  case 3:
+frame->d.~dtor();
+frame->d1.~dtor();
+frame->d2.~dtor();
+break;
+  default: // coroutine completed or haven't started
+break;
+}
+
+frame->promise.~promise_type();
+delete frame;
+  }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` 
to:
+
+.. code-block:: c++
+
+  void foo.destroy(foo.Frame *frame) {
+frame->promise.~promise_type();
+delete frame;
+  }
+
+  }];
+}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0200457b39ce5eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11591,6 +11591,10 @@ def err_conflicting_aligned_options : Error <
 def err_coro_invalid_addr_of_label : Error<
   "the GNU address of label extension is not allowed in coroutines."
 >;
+def err_coroutine_return_type : Error<
+  "function returns a coroutine return type %0 but is neither a coroutine nor 
a coroutine wrapper; "
+  "non-coroutines should be marked with [[clang::coro_wrapper]] to allow 
returning coroutine return type"
+>;
 } // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..4d45698e5786740 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,6 +11183,7 @@ class Sema final {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl

[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

2023-11-17 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 closed https://github.com/llvm/llvm-project/pull/71945
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72516)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 closed https://github.com/llvm/llvm-project/pull/72516
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 created https://github.com/llvm/llvm-project/pull/72851

None

>From 28e9fda4b78e1e60287048891cc92bafdef3ac4c Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH] Introduce [[clang::coro_lifetimebound]]

---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index f7a2b83b15ef5bc..dfe6f8999f832a3 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 438d846c39eaa57..39efaee20694a43 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7540,3 +7539,10 @@ Note: ``a_promise_type::get_return_object`` is exempted 
from this analysis as it
 implementation detail of any coroutine library.
 }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept { return fal

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72851

>From 28e9fda4b78e1e60287048891cc92bafdef3ac4c Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH 1/2] Introduce [[clang::coro_lifetimebound]]

---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index f7a2b83b15ef5bc..dfe6f8999f832a3 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 438d846c39eaa57..39efaee20694a43 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7540,3 +7539,10 @@ Note: ``a_promise_type::get_return_object`` is exempted 
from this analysis as it
 implementation detail of any coroutine library.
 }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept { return false

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72851

>From 28e9fda4b78e1e60287048891cc92bafdef3ac4c Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH 1/3] Introduce [[clang::coro_lifetimebound]]

---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index f7a2b83b15ef5bc..dfe6f8999f832a3 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 438d846c39eaa57..39efaee20694a43 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7540,3 +7539,10 @@ Note: ``a_promise_type::get_return_object`` is exempted 
from this analysis as it
 implementation detail of any coroutine library.
 }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept { return false

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72851
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 ready_for_review 
https://github.com/llvm/llvm-project/pull/72851
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72851

>From 28e9fda4b78e1e60287048891cc92bafdef3ac4c Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH 1/4] Introduce [[clang::coro_lifetimebound]]

---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index f7a2b83b15ef5bc..dfe6f8999f832a3 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 438d846c39eaa57..39efaee20694a43 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7540,3 +7539,10 @@ Note: ``a_promise_type::get_return_object`` is exempted 
from this analysis as it
 implementation detail of any coroutine library.
 }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept { return false

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits


@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-

usx95 wrote:

Acknowledged. Keeping it to match the 1 line space style of the file.

https://github.com/llvm/llvm-project/pull/72851
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72851

>From 28e9fda4b78e1e60287048891cc92bafdef3ac4c Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH 1/5] Introduce [[clang::coro_lifetimebound]]

---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index f7a2b83b15ef5bc..dfe6f8999f832a3 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 438d846c39eaa57..39efaee20694a43 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7540,3 +7539,10 @@ Note: ``a_promise_type::get_return_object`` is exempted 
from this analysis as it
 implementation detail of any coroutine library.
 }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept { return false

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72851

>From 164bf1e94ec05e50be05d085ce2a4381711df11b Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH 1/5] Introduce [[clang::coro_lifetimebound]]

(cherry picked from commit 28e9fda4b78e1e60287048891cc92bafdef3ac4c)
---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index c2fbdfc66c540d6..03ed6accf700c4e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b5ceb47b6b8ad55..8b81926a0477db2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7581,3 +7580,10 @@ alignment boundary. Its value must be a power of 2, 
between 1 and 4096
 
   }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept 

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 reopened 
https://github.com/llvm/llvm-project/pull/72851
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72851

>From 164bf1e94ec05e50be05d085ce2a4381711df11b Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH 1/6] Introduce [[clang::coro_lifetimebound]]

(cherry picked from commit 28e9fda4b78e1e60287048891cc92bafdef3ac4c)
---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index c2fbdfc66c540d6..03ed6accf700c4e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b5ceb47b6b8ad55..8b81926a0477db2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7581,3 +7580,10 @@ alignment boundary. Its value must be a power of 2, 
between 1 and 4096
 
   }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept 

[clang-tools-extra] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 created https://github.com/llvm/llvm-project/pull/72954

None

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH] [clangtidy]Allow safe suspensions in coroutine-hostile-raii
 check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

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


[clang-tools-extra] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 1/2] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 2/2] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

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


[clang-tools-extra] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 1/3] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 2/3] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 3/3] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList)

[llvm] [clang-tools-extra] [mlir] [clang] [flang] [lld] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 1/3] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 2/3] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 3/3] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList)

[flang] [mlir] [clang] [llvm] [lld] [clang-tools-extra] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 1/4] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 2/4] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 3/4] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList)

[clang-tools-extra] 70cfb3a - Revert "Fix tab spaces in coroutine-hostile-raii.cpp"

2023-11-20 Thread Utkarsh Saxena via cfe-commits

Author: Utkarsh Saxena
Date: 2023-11-21T08:08:09+01:00
New Revision: 70cfb3a367f51d805dc5cfc5a54dfc7271a23095

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

LOG: Revert "Fix tab spaces in coroutine-hostile-raii.cpp"

This reverts commit ba3598667f0da87961b6bec390bc7b03cfa72583.

Added: 


Modified: 
clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp

Removed: 




diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 6e8f8e333d4fecb..2d022e21c85d566 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -101,38 +101,38 @@ ReturnObject BasicNoWarning() {
 }
 
 ReturnObject scopedLockableTest() {
-  co_yield 0;
-  absl::Mutex a;
-  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 'a' holds a lock across a 
suspension point of coroutine and could be unlocked by a 
diff erent thread [misc-coroutine-hostile-raii]
-  absl::Mutex2 b;
-  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'b' holds a lock across a 
suspension point of coroutine and could be unlocked by a 
diff erent thread [misc-coroutine-hostile-raii]
-  {
-  absl::Mutex no_warning_1;
-  { absl::Mutex no_warning_2; }
-  }
+co_yield 0;
+absl::Mutex a;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 'a' holds a lock across a 
suspension point of coroutine and could be unlocked by a 
diff erent thread [misc-coroutine-hostile-raii]
+absl::Mutex2 b;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'b' holds a lock across a 
suspension point of coroutine and could be unlocked by a 
diff erent thread [misc-coroutine-hostile-raii]
+{
+absl::Mutex no_warning_1;
+{ absl::Mutex no_warning_2; }
+}
 
-  co_yield 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: note: suspension point is here
-  absl::Mutex c;
-  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 'c' holds a lock across a 
suspension point of coroutine and could be unlocked by a 
diff erent thread [misc-coroutine-hostile-raii]
-  co_await std::suspend_always{};
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: note: suspension point is here
-  for(int i=1; i<=10; ++i ) {
-absl::Mutex d;
-// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 'd' holds a lock across a 
suspension point of coroutine and could be unlocked by a 
diff erent thread [misc-coroutine-hostile-raii]
-co_await std::suspend_always{};
-// CHECK-MESSAGES: :[[@LINE-1]]:7: note: suspension point is here
 co_yield 1;
-absl::Mutex no_warning_3;
-  }
-  if (true) {
-absl::Mutex e;
-// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 'e' holds a lock across a 
suspension point of coroutine and could be unlocked by a 
diff erent thread [misc-coroutine-hostile-raii]
-co_yield 1;
-// CHECK-MESSAGES: :[[@LINE-1]]:7: note: suspension point is here
-absl::Mutex no_warning_4;
-  }
-  absl::Mutex no_warning_5;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: suspension point is here
+absl::Mutex c;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 'c' holds a lock across a 
suspension point of coroutine and could be unlocked by a 
diff erent thread [misc-coroutine-hostile-raii]
+co_await std::suspend_always{};
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: suspension point is here
+for(int i=1; i<=10; ++i ) {
+  absl::Mutex d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 'd' holds a lock across a 
suspension point of coroutine and could be unlocked by a 
diff erent thread [misc-coroutine-hostile-raii]
+  co_await std::suspend_always{};
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: note: suspension point is here
+  co_yield 1;
+  absl::Mutex no_warning_3;
+}
+if (true) {
+  absl::Mutex e;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 'e' holds a lock across a 
suspension point of coroutine and could be unlocked by a 
diff erent thread [misc-coroutine-hostile-raii]
+  co_yield 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: note: suspension point is here
+  absl::Mutex no_warning_4;
+}
+absl::Mutex no_warning_5;
 }
 
 void lambda() {



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


[lld] [llvm] [mlir] [clang-tools-extra] [clang] [flang] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 1/4] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 2/4] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 3/4] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList)

[clang-tools-extra] [flang] [mlir] [clang] [lld] [llvm] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72954
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [flang] [mlir] [clang] [lld] [llvm] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 1/6] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 2/6] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 3/6] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList)

[lld] [flang] [mlir] [llvm] [clang-tools-extra] [clang] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 ready_for_review 
https://github.com/llvm/llvm-project/pull/72954
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [clang-tools-extra] [RFC] Perform lifetime bound checks for arguments to coroutine (PR #69360)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

This was implemented in https://github.com/llvm/llvm-project/pull/72851 and 
https://github.com/llvm/llvm-project/pull/71945. Closing this.

https://github.com/llvm/llvm-project/pull/69360
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang-tools-extra] [clang] [RFC] Perform lifetime bound checks for arguments to coroutine (PR #69360)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 closed https://github.com/llvm/llvm-project/pull/69360
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-21 Thread Utkarsh Saxena via cfe-commits


@@ -7581,3 +7580,59 @@ alignment boundary. Its value must be a power of 2, 
between 1 and 4096
 
   }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The ``[[clang::coro_lifetimebound]]`` is a class attribute which can be applied
+to a `coroutine return type (CRT) 
` _ (i.e.
+it should also be annotated with ``[[clang::coro_return_type]]``).
+
+All arguments to a function are considered to be `lifetime bound 
 _`
+if the function returns a coroutine return type (CRT) annotated with 
``[[clang::coro_lifetimebound]]``.
+
+Reference parameters of a coroutine are susceptible to capturing references to 
temporaries or local variables.
+
+For example,
+
+.. code-block:: c++
+
+  task coro(const int& a) { co_return a + 1; }
+  task dangling_refs(int a) {
+// `coro` captures reference to a temporary. `foo` would now contain a 
dangling reference to `a`.
+auto foo = coro(1);
+// `coro` captures reference to local variable `a` which is destroyed 
after the return. 
+return coro(a);
+  }
+
+`Lifetime bound 
 _` static 
analysis
+can be used to detect such instances when coroutines capture references which 
may die earlier than the
+coroutine frame itself. In the above example, if the CRT `task` is annotated 
with 
+``[[clang::coro_lifetimebound]]``, then lifetime bound analysis would detect 
capturing reference to
+temporaries or return address of a local variable.
+
+Both coroutines and coroutine wrappers are part of this analysis.
+
+.. code-block:: c++
+
+  template  struct [[clang::coro_return_type, 
clang::coro_lifetimebound]] Task {
+using promise_type = some_promise_type;
+  };
+
+  Task coro(const int& a) { co_return a + 1; }
+  Task [[clang::coro_wrapper]] coro_wrapper(const int& a, const int& b) { 
+return a > b ? coro(a) : coro(b);
+  }
+  Task temporary_reference() {
+auto foo = coro(1); // warning: capturing reference to a temporary which 
would die after the expression.
+
+int a = 1;
+auto bar = coro_wrapper(a, 0); // warning: `b` captures reference to a 
temporary.
+
+co_return co_await coro(1); // fine.
+  }
+  Task stack_reference(int a) {

usx95 wrote:

Thanks. Good catch.

https://github.com/llvm/llvm-project/pull/72851
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-21 Thread Utkarsh Saxena via cfe-commits


@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Co {
+  struct promise_type {
+Co get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Co &) {
+  struct awaitable {
+bool await_ready() noexcept { return false; }
+void await_suspend(std::coroutine_handle<>) noexcept {}
+U await_resume() noexcept { return {}; }
+  };
+  return awaitable{};
+}
+  };
+};
+
+Co foo_coro(const int& b) {
+  if (b > 0)
+co_return 1;
+  co_return 2;
+}
+
+int getInt() { return 0; }
+
+Co bar_coro(const int &b, int c) {
+  int x = co_await foo_coro(b);
+  int y = co_await foo_coro(1);
+  int z = co_await foo_coro(getInt());
+  auto unsafe1 = foo_coro(1); // expected-warning {{temporary whose address is 
used as value of local variable}}
+  auto unsafe2 = foo_coro(getInt()); // expected-warning {{temporary whose 
address is used as value of local variable}}
+  auto  safe1 = foo_coro(b);
+  auto  safe2 = foo_coro(c);
+  co_return co_await foo_coro(co_await foo_coro(1));
+}
+
+[[clang::coro_wrapper]] Co plain_return_co(int b) {
+  return foo_coro(b); // expected-warning {{address of stack memory associated 
with parameter}}
+}
+
+[[clang::coro_wrapper]] Co safe_forwarding(const int& b) {
+  return foo_coro(b);
+}
+
+[[clang::coro_wrapper]] Co unsafe_wrapper(int b) {
+  return safe_forwarding(b); // expected-warning {{address of stack memory 
associated with parameter}}
+}
+
+[[clang::coro_wrapper]] Co complex_plain_return(int b) {
+  return b > 0 
+  ? foo_coro(1)   // expected-warning {{returning address of local 
temporary object}}
+  : bar_coro(0, 1); // expected-warning {{returning address of local 
temporary object}}
+}
+
+#define CORO_WRAPPER \
+  _Pragma("clang diagnostic push") \
+  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
+  [[clang::coro_wrapper]] \
+  _Pragma("clang diagnostic pop")
+
+void lambdas() {
+  auto unsafe_lambda = [] CORO_WRAPPER (int b) {
+return foo_coro(b); // expected-warning {{address of stack memory 
associated with parameter}}
+  };
+  auto coro_lambda = [] (const int&) -> Co {
+co_return 0;
+  };
+  auto unsafe_coro_lambda = [&] (const int& b) -> Co {
+int x = co_await coro_lambda(b);
+auto safe = coro_lambda(b);
+auto unsafe1 = coro_lambda(1); // expected-warning {{temporary whose 
address is used as value of local variable}}
+auto unsafe2 = coro_lambda(getInt()); // expected-warning {{temporary 
whose address is used as value of local variable}}
+auto unsafe3 = coro_lambda(co_await coro_lambda(b)); // expected-warning 
{{temporary whose address is used as value of local variable}}
+co_return co_await safe;
+  };
+  auto safe_lambda = [](int b) -> Co {
+int x = co_await foo_coro(1);
+co_return x + co_await foo_coro(b);
+  };
+}
+// 
=
+// Safe usage when parameters are value
+// 
=
+namespace by_value {
+Co value_coro(int b) { co_return co_await foo_coro(b); }
+[[clang::coro_wrapper]] Co wrapper1(int b) { return value_coro(b); }
+[[clang::coro_wrapper]] Co wrapper2(const int& b) { return value_coro(b); 
}
+}
+
+// 
=
+// Lifetime bound but not a Coroutine Return Type: No analysis.
+// 
=
+namespace not_a_crt {
+template  struct [[clang::coro_lifetimebound]] Co {
+  struct promise_type {
+Co get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+  };
+};
+
+Co foo_coro(const int& a) { co_return a; }
+Co bar(int a) { return foo_coro(a); }

usx95 wrote:

Made this a coroutine instead. I do not think `coro_wrapper` is meaningful 
without `coro_return_type`.

https://github.com/llvm/llvm-project/pull/72851
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72851

>From 164bf1e94ec05e50be05d085ce2a4381711df11b Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH 1/7] Introduce [[clang::coro_lifetimebound]]

(cherry picked from commit 28e9fda4b78e1e60287048891cc92bafdef3ac4c)
---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index c2fbdfc66c540d6..03ed6accf700c4e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b5ceb47b6b8ad55..8b81926a0477db2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7581,3 +7580,10 @@ alignment boundary. Its value must be a power of 2, 
between 1 and 4096
 
   }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept 

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72851

>From 164bf1e94ec05e50be05d085ce2a4381711df11b Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH 1/8] Introduce [[clang::coro_lifetimebound]]

(cherry picked from commit 28e9fda4b78e1e60287048891cc92bafdef3ac4c)
---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index c2fbdfc66c540d6..03ed6accf700c4e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b5ceb47b6b8ad55..8b81926a0477db2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7581,3 +7580,10 @@ alignment boundary. Its value must be a power of 2, 
between 1 and 4096
 
   }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept 

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72851

>From 164bf1e94ec05e50be05d085ce2a4381711df11b Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH 1/9] Introduce [[clang::coro_lifetimebound]]

(cherry picked from commit 28e9fda4b78e1e60287048891cc92bafdef3ac4c)
---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index c2fbdfc66c540d6..03ed6accf700c4e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b5ceb47b6b8ad55..8b81926a0477db2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7581,3 +7580,10 @@ alignment boundary. Its value must be a power of 2, 
between 1 and 4096
 
   }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept 

[flang] [mlir] [lld] [llvm] [clang-tools-extra] [clang] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 1/8] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 2/8] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 3/8] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList)

[flang] [mlir] [lld] [llvm] [clang-tools-extra] [clang] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

That is a good solution and does not involve changing the code. Done.

https://github.com/llvm/llvm-project/pull/72954
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [lld] [mlir] [clang-tools-extra] [flang] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 1/9] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 2/9] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 3/9] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList)

[llvm] [clang] [lld] [mlir] [clang-tools-extra] [flang] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 01/10] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 02/10] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 03/10] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesLis

[llvm] [clang] [lld] [mlir] [clang-tools-extra] [flang] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 01/11] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 02/11] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 03/11] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesLis

[llvm] [clang] [lld] [mlir] [clang-tools-extra] [flang] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 01/12] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 02/12] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 03/12] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesLis

[llvm] [clang] [lld] [mlir] [clang-tools-extra] [flang] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/72954
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[flang] [mlir] [lld] [clang-tools-extra] [clang] [llvm] [clangtidy] Allow safe suspensions in coroutine-hostile-raii check (PR #72954)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72954

>From c863646669d0b2b54e1c1c353b063a8209730528 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 06:51:48 +0100
Subject: [PATCH 01/13] [clangtidy]Allow safe suspensions in
 coroutine-hostile-raii check

---
 .../misc/CoroutineHostileRAIICheck.cpp  | 17 -
 .../checkers/misc/coroutine-hostile-raii.cpp| 11 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index e820cd39d83d21b..1c39a6624a1da69 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -52,6 +52,19 @@ AST_MATCHER_P(Stmt, forEachPrevStmt, 
ast_matchers::internal::Matcher,
   }
   return IsHostile;
 }
+
+AST_MATCHER_P(CoawaitExpr, awaiatable, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  return Node.getCommonExpr() &&
+ InnerMatcher.matches(*Node.getCommonExpr(), Finder, Builder);
+}
+
+AST_MATCHER(Decl, isRAIISafeAwaitable) {
+for (const auto &Attr : Node.specific_attrs())
+if (Attr->getAnnotation() == "coro_raii_safe_suspend")
+  return true;
+  return false;
+}
 } // namespace
 
 CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
@@ -68,7 +81,9 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder 
*Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesList))
.bind("raii");
-  Finder->addMatcher(expr(anyOf(coawaitExpr(), coyieldExpr()),
+  auto Allowed = awaiatable(
+  hasType(hasCanonicalType(hasDeclaration(isRAIISafeAwaitable();
+  Finder->addMatcher(expr(anyOf(coawaitExpr(unless(Allowed)), coyieldExpr()),
   forEachPrevStmt(declStmt(forEach(
   varDecl(anyOf(ScopedLockable, OtherRAII))
  .bind("suspension"),
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
index 2d022e21c85d566..4a1dc61b34ded18 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp
@@ -62,6 +62,12 @@ struct suspend_always {
 };
 } // namespace std
 
+struct [[clang::annotate("coro_raii_safe_suspend")]] raii_safe_suspend {
+  bool await_ready() noexcept { return false; }
+  void await_suspend(std::coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
 struct ReturnObject {
 struct promise_type {
 ReturnObject get_return_object() { return {}; }
@@ -135,6 +141,11 @@ ReturnObject scopedLockableTest() {
 absl::Mutex no_warning_5;
 }
 
+ReturnObject RAIISafeSuspendTest() {
+  absl::Mutex a;
+  co_await raii_safe_suspend{};
+} 
+
 void lambda() {
   absl::Mutex no_warning;
   auto lambda = []() -> ReturnObject {

>From b35e1fece9b35f5faf1a28a5fa744ed29ddbf250 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:03:16 +0100
Subject: [PATCH 02/13] fix format

---
 clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 1c39a6624a1da69..235bb584be14754 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P(CoawaitExpr, awaiatable, 
ast_matchers::internal::Matcher,
 }
 
 AST_MATCHER(Decl, isRAIISafeAwaitable) {
-for (const auto &Attr : Node.specific_attrs())
+  for (const auto &Attr : Node.specific_attrs())
 if (Attr->getAnnotation() == "coro_raii_safe_suspend")
   return true;
   return false;

>From 9d1c6d90e3fd7b4eb673bd67ccbf48c1d24ce329 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Tue, 21 Nov 2023 07:06:51 +0100
Subject: [PATCH 03/13] rename var

---
 .../clang-tidy/misc/CoroutineHostileRAIICheck.cpp   | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp 
b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
index 235bb584be14754..6b438b6c44d855c 100644
--- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp
@@ -81,13 +81,14 @@ void 
CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
   auto OtherRAII = varDecl(hasType(hasCanonicalType(hasDeclaration(
namedDecl(hasAnyName(RAIITypesLis

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

I would add the mentioned warning in a follow-up change.

https://github.com/llvm/llvm-project/pull/72851
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-21 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/72851

>From 164bf1e94ec05e50be05d085ce2a4381711df11b Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Mon, 20 Nov 2023 12:17:30 +0100
Subject: [PATCH 01/10] Introduce [[clang::coro_lifetimebound]]

(cherry picked from commit 28e9fda4b78e1e60287048891cc92bafdef3ac4c)
---
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td |  8 +-
 clang/lib/Sema/SemaInit.cpp   |  7 +-
 ...a-attribute-supported-attributes-list.test |  3 +-
 clang/test/SemaCXX/coro-lifetimebound.cpp | 93 +++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/coro-lifetimebound.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index c2fbdfc66c540d6..03ed6accf700c4e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1110,6 +1110,14 @@ def CoroWrapper : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroLifetimeBound : InheritableAttr {
+  let Spellings = [Clang<"coro_lifetimebound">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [CPlusPlus];
+  let Documentation = [CoroLifetimeBoundDoc];
+  let SimpleHandler = 1;
+}
+
 // OSObject-based attributes.
 def OSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"os_consumed">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b5ceb47b6b8ad55..8b81926a0477db2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7483,7 +7483,6 @@ generation of the other destruction cases, optimizing the 
above `foo.destroy` to
   }];
 }
 
-
 def CoroReturnTypeAndWrapperDoc : Documentation {
   let Category = DocCatDecl;
   let Content = [{
@@ -7581,3 +7580,10 @@ alignment boundary. Its value must be a power of 2, 
between 1 and 4096
 
   }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+asdam
+}];
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 80b51b09bf5445f..631b6a266412ccb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7580,10 +7580,15 @@ static void 
visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
   if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
 VisitLifetimeBoundArg(Callee, ObjectArg);
 
+  bool checkCoroCall = false;
+  if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+checkCoroCall |= RD->hasAttr() &&
+ RD->hasAttr();
+  }
   for (unsigned I = 0,
 N = std::min(Callee->getNumParams(), Args.size());
I != N; ++I) {
-if (Callee->getParamDecl(I)->hasAttr())
+if (checkCoroCall || Callee->getParamDecl(I)->hasAttr())
   VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
   }
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a57bc011c059483..dd91f4f88ad685b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -56,9 +56,10 @@
 // CHECK-NEXT: ConsumableAutoCast (SubjectMatchRule_record)
 // CHECK-NEXT: ConsumableSetOnRead (SubjectMatchRule_record)
 // CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: CoroLifetimeBound (SubjectMatchRule_record)
 // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record)
 // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record)
-// CHECK-NEXT: CoroWrapper
+// CHECK-NEXT: CoroWrapper (SubjectMatchRule_function)
 // CHECK-NEXT: CountedBy (SubjectMatchRule_field)
 // CHECK-NEXT: DLLExport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
 // CHECK-NEXT: DLLImport (SubjectMatchRule_function, 
SubjectMatchRule_variable, SubjectMatchRule_record, 
SubjectMatchRule_objc_interface)
diff --git a/clang/test/SemaCXX/coro-lifetimebound.cpp 
b/clang/test/SemaCXX/coro-lifetimebound.cpp
new file mode 100644
index 000..3f719866eae0ee4
--- /dev/null
+++ b/clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+template  struct [[clang::coro_lifetimebound, 
clang::coro_return_type]] Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcep

[clang] [coroutines] Introduce [[clang::coro_lifetimebound]] (PR #72851)

2023-11-22 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 closed https://github.com/llvm/llvm-project/pull/72851
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [RFC] Perform lifetime bound checks for arguments to coroutine (PR #69360)

2023-10-27 Thread Utkarsh Saxena via cfe-commits


@@ -0,0 +1,184 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only 
-verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+
+#define CORO_TYPE [[clang::annotate("coro_type")]]
+#define CORO_UNSAFE [[clang::annotate("coro_unsafe")]]
+
+template  struct CORO_TYPE Gen {
+  struct promise_type {
+Gen get_return_object() {
+  return {};
+}
+suspend_always initial_suspend();
+suspend_always final_suspend() noexcept;
+void unhandled_exception();
+void return_value(const T &t);
+
+template 
+auto await_transform(const Gen &) {
+  struct awaitable {
+bool await_ready() noexcept { return false; }
+void await_suspend(std::coroutine_handle<>) noexcept {}
+U await_resume() noexcept { return {}; }
+  };
+  return awaitable{};
+}
+  };
+};
+
+template  using Co = Gen;
+
+Gen foo_coro(const int& b);
+
+Gen plain_return_foo_decl(int b) {
+  return foo_coro(b); // expected-warning {{address of stack memory associated 
with parameter}}
+}
+
+Gen foo_coro(const int& b) {
+  if (b > 0)
+co_return 1;
+  co_return 2;
+}
+
+int getInt() { return 0; }
+
+Co bar_coro(const int &b, int c) {
+  int x = co_await foo_coro(b);
+  int y = co_await foo_coro(1);

usx95 wrote:

This is because we never emit warnings for `auto x = SomeFunc(foo_coro(1));`
For `co_await` expr, the `func` is `await_transform`. See 
https://godbolt.org/z/soxK1KsWc
The only implementation of awaiter which could be problematic and go undetected 
is when it schedules the foo_coro on other thread.

https://github.com/llvm/llvm-project/pull/69360
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RFC] Perform lifetime bound checks for arguments to coroutine (PR #69360)

2023-10-27 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/69360
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RFC] Perform lifetime bound checks for arguments to coroutine (PR #69360)

2023-10-27 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/69360
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   5   6   7   8   9   10   >