[clang] [clang][ASTImporter] Fix import of anonymous enums if multiple are present (PR #99281)

2024-07-17 Thread Balázs Kéri via cfe-commits

https://github.com/balazske created 
https://github.com/llvm/llvm-project/pull/99281

After the last change in PR #87144 regressions appeared in some cases. The 
problem was that if multiple anonymous enums are present in a class and are 
imported as new the import of the second enum can fail because it is detected 
as different from the first and causes ODR error.

Now in case of enums without name an existing similar enum is searched, if not 
found the enum is imported. ODR error is not detected. This may be incorrect if 
non-matching structures are imported, but this is the less important case 
(import of matching classes is more important to work).

From a4886d59c3a8c7222d80a48206db22a521f5851d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= 
Date: Tue, 16 Jul 2024 18:19:10 +0200
Subject: [PATCH] [clang][ASTImporter] Fix import of anonymous enums if
 multiple are present.

After the last change in PR #87144 regressions appeared in some cases.
The problem was that if multiple anonymous enums are present in a class
and are imported as new the import of the second enum can fail because
it is detected as different from the first and causes ODR error.

Now in case of enums without name an existing similar enum is searched,
if not found the enum is imported. ODR error is not detected. This may
be incorrect if non-matching structures are imported, but this is the
less important case (import of matching classes is more important to
work).
---
 clang/lib/AST/ASTImporter.cpp   |  9 ++-
 clang/unittests/AST/ASTImporterTest.cpp | 95 +
 2 files changed, 89 insertions(+), 15 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 4e1b3a5a94de7..43891d29ad4ea 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -2949,7 +2949,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
   if (auto *FoundEnum = dyn_cast(FoundDecl)) {
 if (!hasSameVisibilityContextAndLinkage(FoundEnum, D))
   continue;
-if (IsStructuralMatch(D, FoundEnum)) {
+if (IsStructuralMatch(D, FoundEnum, !SearchName.isEmpty())) {
   EnumDecl *FoundDef = FoundEnum->getDefinition();
   if (D->isThisDeclarationADefinition() && FoundDef)
 return Importer.MapImported(D, FoundDef);
@@ -2960,7 +2960,12 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) 
{
   }
 }
 
-if (!ConflictingDecls.empty()) {
+// In case of unnamed enums, we try to find an existing similar one, if 
none
+// was found, perform the import always.
+// Structural in-equivalence is not detected in this way here, but it may
+// be found when the parent decl is imported (if the enum is part of a
+// class). To make this totally exact a more difficult solution is needed.
+if (SearchName && !ConflictingDecls.empty()) {
   ExpectedName NameOrErr = Importer.HandleNameConflict(
   SearchName, DC, IDNS, ConflictingDecls.data(),
   ConflictingDecls.size());
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 92f9bae6cb064..6d987cc7e9ec6 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -9681,37 +9681,106 @@ AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, 
ConstName) {
   return false;
 }
 
-TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnums) {
+  const char *Code =
+  R"(
+  struct A {
+enum { E1, E2 } x;
+enum { E3, E4 } y;
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromEnumE1 = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E1")));
+  auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11);
+  EXPECT_TRUE(ImportedEnumE1);
+  auto *FromEnumE3 = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E3")));
+  auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11);
+  EXPECT_TRUE(ImportedEnumE3);
+  EXPECT_NE(ImportedEnumE1, ImportedEnumE3);
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportFreeStandingAnonymousEnums) {
+  const char *Code =
+  R"(
+  struct A {
+enum { E1, E2 };
+enum { E3, E4 };
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromEnumE1 = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E1")));
+  auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11);
+  EXPECT_TRUE(ImportedEnumE1);
+  auto *FromEnumE3 = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E3")));
+  auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11);
+  EXPECT_TRUE(ImportedEnumE3);
+  EXPECT_NE(ImportedEnumE1, ImportedEnumE3);
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingAnonymousEnums) {
   const char *ToCode =
   R"(
   struct A {
-enum { E1, E2} x;
-enum { 

[clang] [clang][ASTImporter] Fix import of anonymous enums if multiple are present (PR #99281)

2024-07-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Balázs Kéri (balazske)


Changes

After the last change in PR #87144 regressions appeared in some cases. 
The problem was that if multiple anonymous enums are present in a class and are 
imported as new the import of the second enum can fail because it is detected 
as different from the first and causes ODR error.

Now in case of enums without name an existing similar enum is searched, if not 
found the enum is imported. ODR error is not detected. This may be incorrect if 
non-matching structures are imported, but this is the less important case 
(import of matching classes is more important to work).

---
Full diff: https://github.com/llvm/llvm-project/pull/99281.diff


2 Files Affected:

- (modified) clang/lib/AST/ASTImporter.cpp (+7-2) 
- (modified) clang/unittests/AST/ASTImporterTest.cpp (+82-13) 


``diff
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 4e1b3a5a94de7..43891d29ad4ea 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -2949,7 +2949,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
   if (auto *FoundEnum = dyn_cast(FoundDecl)) {
 if (!hasSameVisibilityContextAndLinkage(FoundEnum, D))
   continue;
-if (IsStructuralMatch(D, FoundEnum)) {
+if (IsStructuralMatch(D, FoundEnum, !SearchName.isEmpty())) {
   EnumDecl *FoundDef = FoundEnum->getDefinition();
   if (D->isThisDeclarationADefinition() && FoundDef)
 return Importer.MapImported(D, FoundDef);
@@ -2960,7 +2960,12 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) 
{
   }
 }
 
-if (!ConflictingDecls.empty()) {
+// In case of unnamed enums, we try to find an existing similar one, if 
none
+// was found, perform the import always.
+// Structural in-equivalence is not detected in this way here, but it may
+// be found when the parent decl is imported (if the enum is part of a
+// class). To make this totally exact a more difficult solution is needed.
+if (SearchName && !ConflictingDecls.empty()) {
   ExpectedName NameOrErr = Importer.HandleNameConflict(
   SearchName, DC, IDNS, ConflictingDecls.data(),
   ConflictingDecls.size());
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 92f9bae6cb064..6d987cc7e9ec6 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -9681,37 +9681,106 @@ AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, 
ConstName) {
   return false;
 }
 
-TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnums) {
+  const char *Code =
+  R"(
+  struct A {
+enum { E1, E2 } x;
+enum { E3, E4 } y;
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromEnumE1 = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E1")));
+  auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11);
+  EXPECT_TRUE(ImportedEnumE1);
+  auto *FromEnumE3 = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E3")));
+  auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11);
+  EXPECT_TRUE(ImportedEnumE3);
+  EXPECT_NE(ImportedEnumE1, ImportedEnumE3);
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportFreeStandingAnonymousEnums) {
+  const char *Code =
+  R"(
+  struct A {
+enum { E1, E2 };
+enum { E3, E4 };
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromEnumE1 = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E1")));
+  auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11);
+  EXPECT_TRUE(ImportedEnumE1);
+  auto *FromEnumE3 = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E3")));
+  auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11);
+  EXPECT_TRUE(ImportedEnumE3);
+  EXPECT_NE(ImportedEnumE1, ImportedEnumE3);
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingAnonymousEnums) {
   const char *ToCode =
   R"(
   struct A {
-enum { E1, E2} x;
-enum { E3, E4} y;
+enum { E1, E2 } x;
+enum { E3, E4 } y;
   };
   )";
   Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11);
-  auto *ToE1 = FirstDeclMatcher().match(
+  auto *ToEnumE1 = FirstDeclMatcher().match(
   ToTU, enumDecl(hasEnumConstName("E1")));
-  auto *ToE3 = FirstDeclMatcher().match(
+  auto *ToEnumE3 = FirstDeclMatcher().match(
   ToTU, enumDecl(hasEnumConstName("E3")));
   const char *Code =
   R"(
   struct A {
-enum { E1, E2} x;
-enum { E3, E4} y;
+enum { E1, E2 } x;
+enum { E3, E4 } y;
   };
   )";
   Decl *FromTU = getTuDecl(Code, Lang_CXX11);
-  auto *FromE1 = FirstDeclMatcher().match(
+  auto *FromEnumE1 = FirstDeclMatcher().match(
   FromTU, enumDecl(hasEnumConstName("

[clang] [llvm] [Clang] C++20 Coroutines: Introduce Frontend Attribute [[clang::coro_inplace_task]] (PR #99282)

2024-07-17 Thread Yuxuan Chen via cfe-commits

https://github.com/yuxuanchen1997 created 
https://github.com/llvm/llvm-project/pull/99282

This patch is the frontend implementation of the coroutine elide improvement 
project detailed in this discourse post: 
https://discourse.llvm.org/t/language-extension-for-better-more-deterministic-halo-for-c-coroutines/80044

This patch proposes a C++ struct/class attribute 
`[[clang::coro_inplace_task]]`. This notion of inplace task gives developers 
and library authors a certainty that coroutine heap elision happens in a 
predictable way. 

Originally, after we lower a coroutine to LLVM IR, CoroElide is responsible for 
analysis of whether an elision can happen. Take this as an example:
```
Task foo();
Task bar() {
  co_await foo();
}
```
For CoroElide to happen, the ramp function of `foo` must be inlined into `bar`. 
This inlining happens after `foo` has been split but `bar` is usually still a 
presplit coroutine. If `foo` is indeed a coroutine, the inlined `coro.id` 
intrinsics of `foo` is visible within `bar`. CoroElide then runs an analysis to 
figure out whether the SSA value of `coro.begin()` of `foo` gets destroyed 
before `bar` terminates. 

`Task` types are rarely simple enough for the destroy logic of the task to 
reference the SSA value from `coro.begin()` directly. Hence, the pass is very 
ineffective for even the most trivial C++ Task types. Improving CoroElide by 
implementing more powerful analyses is possible, however it doesn't give us the 
predictability when we expect elision to happen. 

The approach we want to take with this language extension generally originates 
from the philosophy that library implementations of `Task` types has the 
control over the structured concurrency guarantees we demand for elision to 
happen. That is, the lifetime for the callee's frame is shorter to that of the 
caller. 

The ``[[clang::coro_inplace_task]]`` is a class attribute which can be applied 
to a coroutine return type.

When a coroutine function that returns such a type calls another coroutine 
function, the compiler performs heap allocation elision when the following 
conditions are all met:
- callee coroutine function returns a type that is annotated with 
``[[clang::coro_inplace_task]]``.
- In caller coroutine, the return value of the callee is a prvalue that is 
immediately `co_await`ed.

>From the C++ perspective, it makes sense because we can ensure the lifetime of 
>elided callee cannot exceed that of the caller if we can guarantee that the 
>caller coroutine is never destroyed earlier than the callee coroutine. This is 
>not generally true for any C++ programs. However, the library that implements 
>`Task` types and executors may provide this guarantee to the compiler, 
>providing the user with certainty that HALO will work on their programs. 

After this patch, when compiling coroutines that return a type with such 
attribute, the frontend checks that the type of the operand of `co_await` 
expressions (not `operator co_await`). If it's also attributed with 
`[[clang::coro_inplace_task]]`, the FE emits metadata on the call or invoke 
instruction as a hint for a later middle end pass to elide the elision. 

The original patch version is https://github.com/llvm/llvm-project/pull/94693 
and as suggested, the patch is split into frontend and middle end solutions 
into stacked PRs. 

The middle end CoroElide patch can be found at .
The middle end transformation that performs the elide can be found at .

>From d38f0608753417c6b79e0684cb9dc23933dc957b Mon Sep 17 00:00:00 2001
From: Yuxuan Chen 
Date: Tue, 4 Jun 2024 23:22:00 -0700
Subject: [PATCH] [Clang] Introduce [[clang::coro_inplace_task]]

Implement noalloc copy

add CoroAnnotationElidePass
---
 clang/include/clang/AST/ExprCXX.h | 26 --
 clang/include/clang/Basic/Attr.td |  8 ++
 clang/include/clang/Basic/AttrDocs.td | 19 
 clang/lib/CodeGen/CGBlocks.cpp|  5 +-
 clang/lib/CodeGen/CGCUDARuntime.cpp   |  5 +-
 clang/lib/CodeGen/CGCUDARuntime.h |  8 +-
 clang/lib/CodeGen/CGCXXABI.h  | 10 +--
 clang/lib/CodeGen/CGClass.cpp | 16 ++--
 clang/lib/CodeGen/CGCoroutine.cpp | 30 +--
 clang/lib/CodeGen/CGExpr.cpp  | 41 +
 clang/lib/CodeGen/CGExprCXX.cpp   | 60 +++--
 clang/lib/CodeGen/CodeGenFunction.h   | 64 --
 clang/lib/CodeGen/ItaniumCXXABI.cpp   | 16 ++--
 clang/lib/CodeGen/MicrosoftCXXABI.cpp | 18 ++--
 clang/lib/Sema/SemaCoroutine.cpp  | 58 -
 clang/lib/Serialization/ASTReaderStmt.cpp | 10 ++-
 clang/lib/Serialization/ASTWriterStmt.cpp |  3 +-
 clang/test/CodeGenCoroutines/Inputs/utility.h | 13 +++
 .../CodeGenCoroutines/coro-must-elide.cpp | 87 +++
 ...a-attribute-supported-attributes-list.test |  1 +
 llvm/include/llvm/Bitcode/LLVMBitCodes.h  |  1 +
 llvm/include/llvm/IR/Attributes.td   

[clang] [llvm] [Clang] C++20 Coroutines: Introduce Frontend Attribute [[clang::coro_inplace_task]] (PR #98971)

2024-07-17 Thread Yuxuan Chen via cfe-commits

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


[clang] [llvm] [Clang] C++20 Coroutines: Introduce Frontend Attribute [[clang::coro_inplace_task]] (PR #98971)

2024-07-17 Thread Yuxuan Chen via cfe-commits

yuxuanchen1997 wrote:

Deprecated in favor of https://github.com/llvm/llvm-project/pull/99282

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


[clang] [llvm] [Clang] C++20 Coroutines: Introduce Frontend Attribute [[clang::coro_inplace_task]] (PR #99282)

2024-07-17 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-coroutines
@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-clang-modules

Author: Yuxuan Chen (yuxuanchen1997)


Changes

This patch is the frontend implementation of the coroutine elide improvement 
project detailed in this discourse post: 
https://discourse.llvm.org/t/language-extension-for-better-more-deterministic-halo-for-c-coroutines/80044

This patch proposes a C++ struct/class attribute 
`[[clang::coro_inplace_task]]`. This notion of inplace task gives developers 
and library authors a certainty that coroutine heap elision happens in a 
predictable way. 

Originally, after we lower a coroutine to LLVM IR, CoroElide is responsible for 
analysis of whether an elision can happen. Take this as an example:
```
Task foo();
Task bar() {
  co_await foo();
}
```
For CoroElide to happen, the ramp function of `foo` must be inlined into `bar`. 
This inlining happens after `foo` has been split but `bar` is usually still a 
presplit coroutine. If `foo` is indeed a coroutine, the inlined `coro.id` 
intrinsics of `foo` is visible within `bar`. CoroElide then runs an analysis to 
figure out whether the SSA value of `coro.begin()` of `foo` gets destroyed 
before `bar` terminates. 

`Task` types are rarely simple enough for the destroy logic of the task to 
reference the SSA value from `coro.begin()` directly. Hence, the pass is very 
ineffective for even the most trivial C++ Task types. Improving CoroElide by 
implementing more powerful analyses is possible, however it doesn't give us the 
predictability when we expect elision to happen. 

The approach we want to take with this language extension generally originates 
from the philosophy that library implementations of `Task` types has the 
control over the structured concurrency guarantees we demand for elision to 
happen. That is, the lifetime for the callee's frame is shorter to that of the 
caller. 

The ``[[clang::coro_inplace_task]]`` is a class attribute which can be applied 
to a coroutine return type.

When a coroutine function that returns such a type calls another coroutine 
function, the compiler performs heap allocation elision when the following 
conditions are all met:
- callee coroutine function returns a type that is annotated with 
``[[clang::coro_inplace_task]]``.
- In caller coroutine, the return value of the callee is a prvalue that is 
immediately `co_await`ed.

>From the C++ perspective, it makes sense because we can ensure the lifetime of 
>elided callee cannot exceed that of the caller if we can guarantee that the 
>caller coroutine is never destroyed earlier than the callee coroutine. This is 
>not generally true for any C++ programs. However, the library that implements 
>`Task` types and executors may provide this guarantee to the compiler, 
>providing the user with certainty that HALO will work on their programs. 

After this patch, when compiling coroutines that return a type with such 
attribute, the frontend checks that the type of the operand of `co_await` 
expressions (not `operator co_await`). If it's also attributed with 
`[[clang::coro_inplace_task]]`, the FE emits metadata on the call or invoke 
instruction as a hint for a later middle end pass to elide the elision. 

The original patch version is https://github.com/llvm/llvm-project/pull/94693 
and as suggested, the patch is split into frontend and middle end solutions 
into stacked PRs. 

The middle end CoroElide patch can be found at .
The middle end transformation that performs the elide can be found at 
.

---

Patch is 52.85 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/99282.diff


24 Files Affected:

- (modified) clang/include/clang/AST/ExprCXX.h (+18-8) 
- (modified) clang/include/clang/Basic/Attr.td (+8) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+19) 
- (modified) clang/lib/CodeGen/CGBlocks.cpp (+3-2) 
- (modified) clang/lib/CodeGen/CGCUDARuntime.cpp (+3-2) 
- (modified) clang/lib/CodeGen/CGCUDARuntime.h (+5-3) 
- (modified) clang/lib/CodeGen/CGCXXABI.h (+5-5) 
- (modified) clang/lib/CodeGen/CGClass.cpp (+6-10) 
- (modified) clang/lib/CodeGen/CGCoroutine.cpp (+21-9) 
- (modified) clang/lib/CodeGen/CGExpr.cpp (+25-16) 
- (modified) clang/lib/CodeGen/CGExprCXX.cpp (+33-27) 
- (modified) clang/lib/CodeGen/CodeGenFunction.h (+37-27) 
- (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+9-7) 
- (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+10-8) 
- (modified) clang/lib/Sema/SemaCoroutine.cpp (+56-2) 
- (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+8-2) 
- (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+2-1) 
- (added) clang/test/CodeGenCoroutines/Inputs/utility.h (+13) 
- (added) clang/test/CodeGenCoroutines/coro-must-elide.cpp (+87) 
- (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test 
(+1) 
- (modified) llvm/include/llvm/Bitcode/LLVMBitCodes.h (+1) 
- (modified) llvm/include/llvm/IR/Attri

[clang] [llvm] [Clang] C++20 Coroutines: Introduce Frontend Attribute [[clang::coro_inplace_task]] (PR #99282)

2024-07-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Yuxuan Chen (yuxuanchen1997)


Changes

This patch is the frontend implementation of the coroutine elide improvement 
project detailed in this discourse post: 
https://discourse.llvm.org/t/language-extension-for-better-more-deterministic-halo-for-c-coroutines/80044

This patch proposes a C++ struct/class attribute 
`[[clang::coro_inplace_task]]`. This notion of inplace task gives developers 
and library authors a certainty that coroutine heap elision happens in a 
predictable way. 

Originally, after we lower a coroutine to LLVM IR, CoroElide is responsible for 
analysis of whether an elision can happen. Take this as an example:
```
Task foo();
Task bar() {
  co_await foo();
}
```
For CoroElide to happen, the ramp function of `foo` must be inlined into `bar`. 
This inlining happens after `foo` has been split but `bar` is usually still a 
presplit coroutine. If `foo` is indeed a coroutine, the inlined `coro.id` 
intrinsics of `foo` is visible within `bar`. CoroElide then runs an analysis to 
figure out whether the SSA value of `coro.begin()` of `foo` gets destroyed 
before `bar` terminates. 

`Task` types are rarely simple enough for the destroy logic of the task to 
reference the SSA value from `coro.begin()` directly. Hence, the pass is very 
ineffective for even the most trivial C++ Task types. Improving CoroElide by 
implementing more powerful analyses is possible, however it doesn't give us the 
predictability when we expect elision to happen. 

The approach we want to take with this language extension generally originates 
from the philosophy that library implementations of `Task` types has the 
control over the structured concurrency guarantees we demand for elision to 
happen. That is, the lifetime for the callee's frame is shorter to that of the 
caller. 

The ``[[clang::coro_inplace_task]]`` is a class attribute which can be applied 
to a coroutine return type.

When a coroutine function that returns such a type calls another coroutine 
function, the compiler performs heap allocation elision when the following 
conditions are all met:
- callee coroutine function returns a type that is annotated with 
``[[clang::coro_inplace_task]]``.
- In caller coroutine, the return value of the callee is a prvalue that is 
immediately `co_await`ed.

>From the C++ perspective, it makes sense because we can ensure the lifetime of 
>elided callee cannot exceed that of the caller if we can guarantee that the 
>caller coroutine is never destroyed earlier than the callee coroutine. This is 
>not generally true for any C++ programs. However, the library that implements 
>`Task` types and executors may provide this guarantee to the compiler, 
>providing the user with certainty that HALO will work on their programs. 

After this patch, when compiling coroutines that return a type with such 
attribute, the frontend checks that the type of the operand of `co_await` 
expressions (not `operator co_await`). If it's also attributed with 
`[[clang::coro_inplace_task]]`, the FE emits metadata on the call or invoke 
instruction as a hint for a later middle end pass to elide the elision. 

The original patch version is https://github.com/llvm/llvm-project/pull/94693 
and as suggested, the patch is split into frontend and middle end solutions 
into stacked PRs. 

The middle end CoroElide patch can be found at .
The middle end transformation that performs the elide can be found at 
.

---

Patch is 52.85 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/99282.diff


24 Files Affected:

- (modified) clang/include/clang/AST/ExprCXX.h (+18-8) 
- (modified) clang/include/clang/Basic/Attr.td (+8) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+19) 
- (modified) clang/lib/CodeGen/CGBlocks.cpp (+3-2) 
- (modified) clang/lib/CodeGen/CGCUDARuntime.cpp (+3-2) 
- (modified) clang/lib/CodeGen/CGCUDARuntime.h (+5-3) 
- (modified) clang/lib/CodeGen/CGCXXABI.h (+5-5) 
- (modified) clang/lib/CodeGen/CGClass.cpp (+6-10) 
- (modified) clang/lib/CodeGen/CGCoroutine.cpp (+21-9) 
- (modified) clang/lib/CodeGen/CGExpr.cpp (+25-16) 
- (modified) clang/lib/CodeGen/CGExprCXX.cpp (+33-27) 
- (modified) clang/lib/CodeGen/CodeGenFunction.h (+37-27) 
- (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+9-7) 
- (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+10-8) 
- (modified) clang/lib/Sema/SemaCoroutine.cpp (+56-2) 
- (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+8-2) 
- (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+2-1) 
- (added) clang/test/CodeGenCoroutines/Inputs/utility.h (+13) 
- (added) clang/test/CodeGenCoroutines/coro-must-elide.cpp (+87) 
- (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test 
(+1) 
- (modified) llvm/include/llvm/Bitcode/LLVMBitCodes.h (+1) 
- (modified) llvm/include/llvm/IR/Attributes.td (+3) 
- (modified) llvm/lib/Bitcode/Writer/BitcodeWriter.cpp (+2) 
- (modified) llvm/lib/Transf

[clang] [libc] [libcxx] [libc][libcxx] Support for building libc++ against LLVM libc (PR #99287)

2024-07-17 Thread Petr Hosek via cfe-commits

https://github.com/petrhosek created 
https://github.com/llvm/llvm-project/pull/99287

Provide an option to build libc++ against LLVM libc and set the CMake compile 
and link options appropriately when the option is enabled.

>From 7d7a7882b713e056f9194b2dd7d792fb9bb86bb5 Mon Sep 17 00:00:00 2001
From: Petr Hosek 
Date: Wed, 17 Jul 2024 00:32:39 -0700
Subject: [PATCH] [libc][libcxx] Support for building libc++ against LLVM libc

Provide an option to build libc++ against LLVM libc and set the CMake
compile and link options appropriately when the option is enabled.
---
 clang/cmake/caches/Fuchsia-stage2.cmake|  2 ++
 libc/cmake/modules/CheckCompilerFeatures.cmake |  3 +++
 libc/include/CMakeLists.txt|  3 +++
 libc/lib/CMakeLists.txt|  5 -
 libcxx/CMakeLists.txt  |  1 +
 libcxx/include/CMakeLists.txt  |  3 +++
 libcxx/src/CMakeLists.txt  | 10 ++
 7 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake 
b/clang/cmake/caches/Fuchsia-stage2.cmake
index b4561e6c87ba5..dc9b596b4ba8f 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -338,6 +338,7 @@ foreach(target 
armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m.main-unknown-eabi)
   set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
+  set(RUNTIMES_${target}_LIBCXX_USE_LLVM_LIBC ON CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
@@ -388,6 +389,7 @@ foreach(target riscv32-unknown-elf)
   set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
+  set(RUNTIMES_${target}_LIBCXX_USE_LLVM_LIBC ON CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake 
b/libc/cmake/modules/CheckCompilerFeatures.cmake
index a6d793d495c45..d64d9de97af3c 100644
--- a/libc/cmake/modules/CheckCompilerFeatures.cmake
+++ b/libc/cmake/modules/CheckCompilerFeatures.cmake
@@ -102,3 +102,6 @@ check_cxx_compiler_flag("-nostdlib++" 
LIBC_CC_SUPPORTS_NOSTDLIBPP)
 
 # clang-3.0+
 check_cxx_compiler_flag("-nostdlibinc" LIBC_CC_SUPPORTS_NOSTDLIBINC)
+
+# clang-3.0+
+check_cxx_compiler_flag("-nolibc" LIBC_CC_SUPPORTS_NOLIBC)
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 2cf7206f3a625..d521e205df8c3 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -664,6 +664,9 @@ get_all_install_header_targets(all_install_header_targets 
${TARGET_PUBLIC_HEADER
 add_library(libc-headers INTERFACE)
 add_dependencies(libc-headers ${all_install_header_targets})
 target_include_directories(libc-headers SYSTEM INTERFACE ${LIBC_INCLUDE_DIR})
+if(LIBC_CC_SUPPORTS_NOSTDLIBINC)
+  target_compile_options(libc-headers INTERFACE "-nostdlibinc")
+endif()
 
 foreach(target IN LISTS all_install_header_targets)
   get_target_property(header_file ${target} HEADER_FILE_PATH)
diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index 37acf3950b460..7e18f35e7d60e 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -30,7 +30,10 @@ foreach(archive IN ZIP_LISTS
   ARCHIVE_OUTPUT_NAME ${archive_0}
   )
   if(LLVM_LIBC_FULL_BUILD)
-target_link_libraries(${archive_1} PUBLIC libc-headers)
+target_link_libraries(${archive_1} INTERFACE libc-headers)
+if(LIBC_CC_SUPPORTS_NOLIBC)
+  target_link_options(${archive_1} INTERFACE "-nolibc")
+endif()
 if(TARGET libc-startup)
   add_dependencies(${archive_1} libc-startup)
 endif()
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 190a97db9462f..5a568e95b239e 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -293,6 +293,7 @@ option(LIBCXX_ENABLE_THREADS "Build libc++ with support for 
threads." ON)
 option(LIBCXX_ENABLE_MONOTONIC_CLOCK
   "Build libc++ with support for a monotonic clock.
This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON)
+option(LIBCXX_USE_LLVM_LIBC "Build libc++ against LLVM libc." OFF)
 option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" 
OFF)
 option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread 
API" OFF)
 option(LIBCXX_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of 
win32 thread API" OFF)
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMa

[clang] [libc] [libcxx] [libc][libcxx] Support for building libc++ against LLVM libc (PR #99287)

2024-07-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-libc

Author: Petr Hosek (petrhosek)


Changes

Provide an option to build libc++ against LLVM libc and set the CMake compile 
and link options appropriately when the option is enabled.

---
Full diff: https://github.com/llvm/llvm-project/pull/99287.diff


7 Files Affected:

- (modified) clang/cmake/caches/Fuchsia-stage2.cmake (+2) 
- (modified) libc/cmake/modules/CheckCompilerFeatures.cmake (+3) 
- (modified) libc/include/CMakeLists.txt (+3) 
- (modified) libc/lib/CMakeLists.txt (+4-1) 
- (modified) libcxx/CMakeLists.txt (+1) 
- (modified) libcxx/include/CMakeLists.txt (+3) 
- (modified) libcxx/src/CMakeLists.txt (+10) 


``diff
diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake 
b/clang/cmake/caches/Fuchsia-stage2.cmake
index b4561e6c87ba5..dc9b596b4ba8f 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -338,6 +338,7 @@ foreach(target 
armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m.main-unknown-eabi)
   set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
+  set(RUNTIMES_${target}_LIBCXX_USE_LLVM_LIBC ON CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
@@ -388,6 +389,7 @@ foreach(target riscv32-unknown-elf)
   set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
+  set(RUNTIMES_${target}_LIBCXX_USE_LLVM_LIBC ON CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake 
b/libc/cmake/modules/CheckCompilerFeatures.cmake
index a6d793d495c45..d64d9de97af3c 100644
--- a/libc/cmake/modules/CheckCompilerFeatures.cmake
+++ b/libc/cmake/modules/CheckCompilerFeatures.cmake
@@ -102,3 +102,6 @@ check_cxx_compiler_flag("-nostdlib++" 
LIBC_CC_SUPPORTS_NOSTDLIBPP)
 
 # clang-3.0+
 check_cxx_compiler_flag("-nostdlibinc" LIBC_CC_SUPPORTS_NOSTDLIBINC)
+
+# clang-3.0+
+check_cxx_compiler_flag("-nolibc" LIBC_CC_SUPPORTS_NOLIBC)
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 2cf7206f3a625..d521e205df8c3 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -664,6 +664,9 @@ get_all_install_header_targets(all_install_header_targets 
${TARGET_PUBLIC_HEADER
 add_library(libc-headers INTERFACE)
 add_dependencies(libc-headers ${all_install_header_targets})
 target_include_directories(libc-headers SYSTEM INTERFACE ${LIBC_INCLUDE_DIR})
+if(LIBC_CC_SUPPORTS_NOSTDLIBINC)
+  target_compile_options(libc-headers INTERFACE "-nostdlibinc")
+endif()
 
 foreach(target IN LISTS all_install_header_targets)
   get_target_property(header_file ${target} HEADER_FILE_PATH)
diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index 37acf3950b460..7e18f35e7d60e 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -30,7 +30,10 @@ foreach(archive IN ZIP_LISTS
   ARCHIVE_OUTPUT_NAME ${archive_0}
   )
   if(LLVM_LIBC_FULL_BUILD)
-target_link_libraries(${archive_1} PUBLIC libc-headers)
+target_link_libraries(${archive_1} INTERFACE libc-headers)
+if(LIBC_CC_SUPPORTS_NOLIBC)
+  target_link_options(${archive_1} INTERFACE "-nolibc")
+endif()
 if(TARGET libc-startup)
   add_dependencies(${archive_1} libc-startup)
 endif()
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 190a97db9462f..5a568e95b239e 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -293,6 +293,7 @@ option(LIBCXX_ENABLE_THREADS "Build libc++ with support for 
threads." ON)
 option(LIBCXX_ENABLE_MONOTONIC_CLOCK
   "Build libc++ with support for a monotonic clock.
This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON)
+option(LIBCXX_USE_LLVM_LIBC "Build libc++ against LLVM libc." OFF)
 option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" 
OFF)
 option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread 
API" OFF)
 option(LIBCXX_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of 
win32 thread API" OFF)
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index cd64fe91449c2..31a819932d521 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -1043,6 +1043,9 @@ add_custom_target(generate-cxx-headers ALL DEPENDS 
${_all_includes})
 
 add_library(cxx-headers INTERFACE)
 target_link_libraries(cxx-headers INTERFACE libcxx-abi-headers)
+if (LIBCXX_USE_LLVM_LI

[clang] [libc] [libcxx] [libc][libcxx] Support for building libc++ against LLVM libc (PR #99287)

2024-07-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-libcxx

Author: Petr Hosek (petrhosek)


Changes

Provide an option to build libc++ against LLVM libc and set the CMake compile 
and link options appropriately when the option is enabled.

---
Full diff: https://github.com/llvm/llvm-project/pull/99287.diff


7 Files Affected:

- (modified) clang/cmake/caches/Fuchsia-stage2.cmake (+2) 
- (modified) libc/cmake/modules/CheckCompilerFeatures.cmake (+3) 
- (modified) libc/include/CMakeLists.txt (+3) 
- (modified) libc/lib/CMakeLists.txt (+4-1) 
- (modified) libcxx/CMakeLists.txt (+1) 
- (modified) libcxx/include/CMakeLists.txt (+3) 
- (modified) libcxx/src/CMakeLists.txt (+10) 


``diff
diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake 
b/clang/cmake/caches/Fuchsia-stage2.cmake
index b4561e6c87ba5..dc9b596b4ba8f 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -338,6 +338,7 @@ foreach(target 
armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m.main-unknown-eabi)
   set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
+  set(RUNTIMES_${target}_LIBCXX_USE_LLVM_LIBC ON CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
@@ -388,6 +389,7 @@ foreach(target riscv32-unknown-elf)
   set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
+  set(RUNTIMES_${target}_LIBCXX_USE_LLVM_LIBC ON CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
   set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake 
b/libc/cmake/modules/CheckCompilerFeatures.cmake
index a6d793d495c45..d64d9de97af3c 100644
--- a/libc/cmake/modules/CheckCompilerFeatures.cmake
+++ b/libc/cmake/modules/CheckCompilerFeatures.cmake
@@ -102,3 +102,6 @@ check_cxx_compiler_flag("-nostdlib++" 
LIBC_CC_SUPPORTS_NOSTDLIBPP)
 
 # clang-3.0+
 check_cxx_compiler_flag("-nostdlibinc" LIBC_CC_SUPPORTS_NOSTDLIBINC)
+
+# clang-3.0+
+check_cxx_compiler_flag("-nolibc" LIBC_CC_SUPPORTS_NOLIBC)
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 2cf7206f3a625..d521e205df8c3 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -664,6 +664,9 @@ get_all_install_header_targets(all_install_header_targets 
${TARGET_PUBLIC_HEADER
 add_library(libc-headers INTERFACE)
 add_dependencies(libc-headers ${all_install_header_targets})
 target_include_directories(libc-headers SYSTEM INTERFACE ${LIBC_INCLUDE_DIR})
+if(LIBC_CC_SUPPORTS_NOSTDLIBINC)
+  target_compile_options(libc-headers INTERFACE "-nostdlibinc")
+endif()
 
 foreach(target IN LISTS all_install_header_targets)
   get_target_property(header_file ${target} HEADER_FILE_PATH)
diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index 37acf3950b460..7e18f35e7d60e 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -30,7 +30,10 @@ foreach(archive IN ZIP_LISTS
   ARCHIVE_OUTPUT_NAME ${archive_0}
   )
   if(LLVM_LIBC_FULL_BUILD)
-target_link_libraries(${archive_1} PUBLIC libc-headers)
+target_link_libraries(${archive_1} INTERFACE libc-headers)
+if(LIBC_CC_SUPPORTS_NOLIBC)
+  target_link_options(${archive_1} INTERFACE "-nolibc")
+endif()
 if(TARGET libc-startup)
   add_dependencies(${archive_1} libc-startup)
 endif()
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 190a97db9462f..5a568e95b239e 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -293,6 +293,7 @@ option(LIBCXX_ENABLE_THREADS "Build libc++ with support for 
threads." ON)
 option(LIBCXX_ENABLE_MONOTONIC_CLOCK
   "Build libc++ with support for a monotonic clock.
This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON)
+option(LIBCXX_USE_LLVM_LIBC "Build libc++ against LLVM libc." OFF)
 option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" 
OFF)
 option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread 
API" OFF)
 option(LIBCXX_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of 
win32 thread API" OFF)
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index cd64fe91449c2..31a819932d521 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -1043,6 +1043,9 @@ add_custom_target(generate-cxx-headers ALL DEPENDS 
${_all_includes})
 
 add_library(cxx-headers INTERFACE)
 target_link_libraries(cxx-headers INTERFACE libcxx-abi-headers)
+if (LIBCXX_USE_LLVM_

[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-17 Thread Balazs Benics via cfe-commits
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann 
Message-ID:
In-Reply-To: 


https://github.com/steakhal approved this pull request.

I think it's already in a good shape. I found barely any problems with the 
wording.

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


[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-17 Thread Balazs Benics via cfe-commits
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann 
Message-ID:
In-Reply-To: 



@@ -363,6 +397,18 @@ class LazyCompoundVal : public NonLoc {
   /// It might return null.
   const void *getStore() const;
 
+  /// This function itself is immaterial. It is only an implementation detail.
+  /// LazyCompoundVal represents only the rvalue, the data (known or unknown)
+  /// that *was* stored in that region *at some point in the past*. The region
+  /// should not be used for any purpose other than figuring out what part of
+  /// the frozen Store you're interested in. The value does not represent the
+  /// *current* value of that region. Sometimes it may, but this should not be
+  /// relied upon. Instead, if you want to figure out what region it 
represents,
+  /// you typically need to see where you got it from in the first place. The
+  /// region is absolutely not analogous to the C++ "this" pointer. It is also
+  /// not a valid way to "materialize" the prvalue into a glvalue in C++,
+  /// because the region represents the *old* storage (sometimes very old), not
+  /// the *future* storage.

steakhal wrote:

To be fair, I don't really understand this.

To me, this region is the region that one would need to query from the 
associated `Store` to get the value this `LazyCompoundValue` actually boils 
down to.
So, a region, like every other region, only defines a memory location (an 
l-value), and there is not much one could do with such a region. But I find 
this true for any other `MemRegion` anywhere in the engine.

Probably I miss something, as I don't usually deal with LCVs, and it's been a 
while I last touched them.
So, to summarize, I don't really understand what `immaterial` means in this 
context or understand why we mention it for `LCV::getRegion()` instead of 
mention this for a `MemRegion`.

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


[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-17 Thread Balazs Benics via cfe-commits
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann 
Message-ID:
In-Reply-To: 


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


[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-17 Thread Balazs Benics via cfe-commits
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann 
Message-ID:
In-Reply-To: 



@@ -346,6 +350,36 @@ class CompoundVal : public NonLoc {
   static bool classof(SVal V) { return V.getKind() == CompoundValKind; }
 };
 
+/// While nonloc::CompoundVal covers a few simple use cases,
+/// nonloc::LazyCompoundVal is a more performant and flexible way to represent
+/// an rvalue of record type, so it shows up much more frequently during
+/// analysis. This value is an r-value that represents a snapshot of any
+/// structure "as a whole" at a given moment during the analysis. Such value is
+/// already quite far from being referred to as "concrete", as many fields
+/// inside it would be unknown or symbolic. nonloc::LazyCompoundVal operates by
+/// storing two things:
+///   * a reference to the TypedValueRegion being snapshotted (yes, it is 
always
+/// typed), and also
+///  * a reference to the whole Store object, obtained from the ProgramState in
+///which the nonloc::LazyCompoundVal was created.
+///
+/// Note that the old ProgramState and its Store is kept alive during the
+/// analysis because these are immutable functional data structures and each 
new
+/// Store value is represented as "earlier Store" + "additional binding".
+///
+/// Essentially, nonloc::LazyCompoundVal is a performance optimization for the
+/// analyzer. Because Store is immutable, creating a nonloc::LazyCompoundVal is
+/// a very cheap operation. Note that the Store contains all region bindings in
+/// the program state, not only related to the region. Later, if necessary, 
such
+/// value can be unpacked -- eg. when it is assigned to another variable.
+///
+/// If you ever need inspect the contents of the LazyCompoundVal, you can use

steakhal wrote:

```suggestion
/// If you ever need to inspect the contents of the LazyCompoundVal, you can use
```

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


[clang] [analyzer][NFC] Add some docs for LazyCompoundValue (PR #97407)

2024-07-17 Thread Balazs Benics via cfe-commits
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann ,
=?utf-8?q?Kristóf?= Umann 
Message-ID:
In-Reply-To: 



@@ -346,6 +350,36 @@ class CompoundVal : public NonLoc {
   static bool classof(SVal V) { return V.getKind() == CompoundValKind; }
 };
 
+/// While nonloc::CompoundVal covers a few simple use cases,
+/// nonloc::LazyCompoundVal is a more performant and flexible way to represent
+/// an rvalue of record type, so it shows up much more frequently during
+/// analysis. This value is an r-value that represents a snapshot of any
+/// structure "as a whole" at a given moment during the analysis. Such value is
+/// already quite far from being referred to as "concrete", as many fields
+/// inside it would be unknown or symbolic. nonloc::LazyCompoundVal operates by
+/// storing two things:
+///   * a reference to the TypedValueRegion being snapshotted (yes, it is 
always
+/// typed), and also
+///  * a reference to the whole Store object, obtained from the ProgramState in
+///which the nonloc::LazyCompoundVal was created.

steakhal wrote:

These bulletpoints are indented by different levels.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Pavel Skripkin via cfe-commits


@@ -14,6 +14,13 @@
 void free(void *);
 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
 
+void __attribute((ownership_returns(malloc1))) *my_malloc1(size_t);
+void __attribute((ownership_takes(malloc1, 1))) my_free1(void *);
+
+void __attribute((ownership_returns(malloc2))) *my_malloc2(size_t);
+void __attribute((ownership_returns(malloc2))) *my_malloc3(size_t);
+void __attribute((ownership_takes(malloc2, 1))) 
__attribute((ownership_takes(malloc3, 1))) my_free23(void *);

pskrgag wrote:

I also find this quite strange, but can't say if there are any real-world 
examples of function that takes ownership of 2 different classes.

Maybe it would be better to just disallow 2 different classes?

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


[clang] a5b5208 - [clang] Be careful when choosing "fast path" for initialization with #embed (#99023)

2024-07-17 Thread via cfe-commits

Author: Mariya Podchishchaeva
Date: 2024-07-17T10:00:47+02:00
New Revision: a5b5208ba627da46310db67af0dcbb0a824fab92

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

LOG: [clang] Be careful when choosing "fast path" for initialization with 
#embed (#99023)

When #embed appears in an initializer list, we may choose a "fast path"
if the target declaration is a char array. We simply initialize it with
string literal that contains embedded data. However we need to be
careful when checking that we actually can use this "fast path" since
char array may be nested in a struct.

Added: 


Modified: 
clang/lib/Sema/SemaInit.cpp
clang/test/Preprocessor/embed_codegen.cpp
clang/test/Preprocessor/embed_constexpr.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index a27ed02fc73b8..d97a5c8988840 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -1993,9 +1993,18 @@ static bool checkDestructorReference(QualType 
ElementType, SourceLocation Loc,
   return SemaRef.DiagnoseUseOfDecl(Destructor, Loc);
 }
 
-static bool canInitializeArrayWithEmbedDataString(ArrayRef ExprList,
-  QualType InitType,
-  ASTContext &Context) {
+static bool
+canInitializeArrayWithEmbedDataString(ArrayRef ExprList,
+  const InitializedEntity &Entity,
+  ASTContext &Context) {
+  QualType InitType = Entity.getType();
+  const InitializedEntity *Parent = &Entity;
+
+  while (Parent) {
+InitType = Parent->getType();
+Parent = Parent->getParent();
+  }
+
   // Only one initializer, it's an embed and the types match;
   EmbedExpr *EE =
   ExprList.size() == 1
@@ -2034,7 +2043,7 @@ void InitListChecker::CheckArrayType(const 
InitializedEntity &Entity,
 }
   }
 
-  if (canInitializeArrayWithEmbedDataString(IList->inits(), DeclType,
+  if (canInitializeArrayWithEmbedDataString(IList->inits(), Entity,
 SemaRef.Context)) {
 EmbedExpr *Embed = cast(IList->inits()[0]);
 IList->setInit(0, Embed->getDataStringLiteral());

diff  --git a/clang/test/Preprocessor/embed_codegen.cpp 
b/clang/test/Preprocessor/embed_codegen.cpp
index 201bf300bc669..2cf14d8d6a15d 100644
--- a/clang/test/Preprocessor/embed_codegen.cpp
+++ b/clang/test/Preprocessor/embed_codegen.cpp
@@ -3,6 +3,7 @@
 // CHECK: @__const._Z3fooi.ca = private unnamed_addr constant [3 x i32] [i32 
0, i32 106, i32 107], align 4
 // CHECK: @__const._Z3fooi.sc = private unnamed_addr constant %struct.S1 { i32 
106, i32 107, i32 0 }, align 4
 // CHECK: @__const._Z3fooi.t = private unnamed_addr constant [3 x %struct.T] 
[%struct.T { [2 x i32] [i32 48, i32 49], %struct.S1 { i32 50, i32 51, i32 52 } 
}, %struct.T { [2 x i32] [i32 53, i32 54], %struct.S1 { i32 55, i32 56, i32 57 
} }, %struct.T { [2 x i32] [i32 10, i32 0], %struct.S1 zeroinitializer }], 
align 16
+// CHECK: @__const._Z3fooi.W = private unnamed_addr constant %struct.Wrapper { 
i32 48, %struct.HasCharArray { [10 x i8] c"123456789\0A" } }, align 4
 void foo(int a) {
 // CHECK: %a.addr = alloca i32, align 4
 // CHECK: store i32 %a, ptr %a.addr, align 4
@@ -82,4 +83,11 @@ struct T tnonc[] = {
 #embed  prefix(,)
 };
 
+
+struct HasCharArray { unsigned char h[10]; };
+struct Wrapper { int a; struct HasCharArray d;  };
+constexpr struct Wrapper W = {
+#embed "numbers.txt"
+};
+
 }

diff  --git a/clang/test/Preprocessor/embed_constexpr.cpp 
b/clang/test/Preprocessor/embed_constexpr.cpp
index a7857641a2e8d..c51c02def7dfb 100644
--- a/clang/test/Preprocessor/embed_constexpr.cpp
+++ b/clang/test/Preprocessor/embed_constexpr.cpp
@@ -96,3 +96,11 @@ struct ST {};
 ST<
 #embed  limit(1)
 > st;
+
+struct HasCharArray { unsigned char h[10]; };
+struct Wrapper { int a; struct HasCharArray d;  };
+constexpr struct Wrapper W = {
+#embed "numbers.txt"
+};
+
+static_assert(W.d.h[2] == '3');



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


[clang] [clang] Be careful when choosing "fast path" for initialization with #embed (PR #99023)

2024-07-17 Thread Mariya Podchishchaeva via cfe-commits

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


[clang-tools-extra] 0905732 - [clang-tools-extra] Fix typos in Modularize.rst (#99256)

2024-07-17 Thread via cfe-commits

Author: Abe
Date: 2024-07-17T09:07:17+01:00
New Revision: 0905732f75cb0f774972c721810aba74021102f2

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

LOG: [clang-tools-extra] Fix typos in Modularize.rst (#99256)

mainly, fixed “the Clang module mechanism doesn’t support headers the
rely on other headers” => “the Clang module mechanism doesn’t support
headers that rely on other headers”. [emphasis on “the” versus “that”]

Added: 


Modified: 
clang-tools-extra/docs/modularize.rst

Removed: 




diff  --git a/clang-tools-extra/docs/modularize.rst 
b/clang-tools-extra/docs/modularize.rst
index 64ca8c99d4e8e..97fd33b958650 100644
--- a/clang-tools-extra/docs/modularize.rst
+++ b/clang-tools-extra/docs/modularize.rst
@@ -254,8 +254,8 @@ For example, with the same header list from above::
   }
 
 Note that headers with dependents will be ignored with a warning, as the
-Clang module mechanism doesn't support headers the rely on other headers
-to be included first.
+Clang module mechanism doesn't support headers that rely on other headers
+being included first.
 
 The module map format defines some keywords which can't be used in module
 names. If a header has one of these names, an underscore ('_') will be



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


[clang-tools-extra] [clang-tools-extra] Fix typos in Modularize.rst (PR #99256)

2024-07-17 Thread David Spickett via cfe-commits

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


[clang-tools-extra] [clang-tools-extra] Fix typos in Modularize.rst (PR #99256)

2024-07-17 Thread via cfe-commits

github-actions[bot] wrote:



@Abe149 Congratulations on having your first Pull Request (PR) merged into the 
LLVM Project!

Your changes will be combined with recent changes from other authors, then 
tested
by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with 
a build, you may receive a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as
the builds can include changes from many authors. It is not uncommon for your
change to be included in a build that fails due to someone else's changes, or
infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail 
[here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr).

If your change does cause a problem, it may be reverted, or you can revert it 
yourself.
This is a normal part of [LLVM 
development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy).
 You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are 
working as expected, well done!


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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Pavel Skripkin via cfe-commits


@@ -103,14 +103,46 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+class AllocationFamily {
+public:
+  AllocationFamily(AllocationFamilyKind kind,

pskrgag wrote:

Marking with `explicit` would cause compile errors for code like `family == 
AF_Smth`. We could wrap all `AF_*` with direct constructor call, but, I think, 
it would be less clean. What do you think?



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


[clang-tools-extra] [clang-tools-extra] Fix typos in Modularize.rst (PR #99256)

2024-07-17 Thread David Spickett via cfe-commits

DavidSpickett wrote:

I saw your email in the merge box so I've gone ahead and landed it (I think the 
workflow that checks for a private email may only be re-run when the changes in 
the PR are updated).

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Pavel Skripkin via cfe-commits


@@ -1918,26 +1982,54 @@ static bool printMemFnName(raw_ostream &os, 
CheckerContext &C, const Expr *E) {
 
 static void printExpectedAllocName(raw_ostream &os, AllocationFamily Family) {
 
-  switch(Family) {
-case AF_Malloc: os << "malloc()"; return;
-case AF_CXXNew: os << "'new'"; return;
-case AF_CXXNewArray: os << "'new[]'"; return;
-case AF_IfNameIndex: os << "'if_nameindex()'"; return;
-case AF_InnerBuffer: os << "container-specific allocator"; return;
-case AF_Alloca:
-case AF_None: llvm_unreachable("not a deallocation expression");
+  switch (Family.kind()) {
+  case AF_Malloc:
+os << "malloc()";
+return;
+  case AF_CXXNew:
+os << "'new'";
+return;
+  case AF_CXXNewArray:
+os << "'new[]'";
+return;
+  case AF_IfNameIndex:
+os << "'if_nameindex()'";
+return;
+  case AF_InnerBuffer:
+os << "container-specific allocator";
+return;
+  case AF_Custom:
+os << Family.name().value();
+return;
+  case AF_Alloca:
+  case AF_None:
+llvm_unreachable("not a deallocation expression");

pskrgag wrote:

I think, all `llvm_unreachable` s  in this file could be turned in `assert` , 
since they just check sanity of calling contract. Will clean up all of them in 
separate patch, thanks!

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


[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-17 Thread Daniil Kovalev via cfe-commits

https://github.com/kovdan01 approved this pull request.

LGTM, thanks @ahatanak !

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


[clang] [Concepts] Avoid substituting into constraints for invalid TemplateDecls (PR #75697)

2024-07-17 Thread via cfe-commits

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


[clang] [Concepts] Avoid substituting into constraints for invalid TemplateDecls (PR #75697)

2024-07-17 Thread via cfe-commits

https://github.com/cor3ntin approved this pull request.

LGTM modulo comments

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


[clang] [Concepts] Avoid substituting into constraints for invalid TemplateDecls (PR #75697)

2024-07-17 Thread via cfe-commits


@@ -483,6 +483,13 @@ bool Sema::CheckConstraintSatisfaction(
 *this, nullptr, ConstraintExprs, ConvertedConstraints,
 TemplateArgsLists, TemplateIDRange, OutSatisfaction);
   }
+  // Invalid templates could make their way here. Substituting them could 
result
+  // in dependent expressions.
+  // FIXME: Say something in the diagnostic note?

cor3ntin wrote:

I don't think we need that fixme. It would be weird to say "note: because foo 
is invalid" - we usually don;t do that and it's not useful unless we can 
explain _why_ it is invalid

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


[clang] [Concepts] Avoid substituting into constraints for invalid TemplateDecls (PR #75697)

2024-07-17 Thread via cfe-commits


@@ -227,3 +227,20 @@ struct r6 {};
 
 using r6i = r6;
 // expected-error@-1 {{constraints not satisfied for class template 'r6' [with 
T = int]}}
+
+namespace GH73885 {
+
+template  // expected-error {{extraneous}}
+template  requires(T{})
+bool e_v = true;
+
+static_assert(e_v);
+
+// We do accept the following as an extension. See 
Sema::MatchTemplateParametersToScopeSpecifier()
+template <>  // expected-warning {{extraneous}}
+template  requires(T{true})
+constexpr bool e = true;

cor3ntin wrote:

Really? 
This  is... wild. Is that intentional?

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


[clang] [clang-format] Add BinPackBinaryOperations configuration (PR #95013)

2024-07-17 Thread via cfe-commits

mydeveloperday wrote:

I'm not finding the true/false every clear, can we use an enum?

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


[clang] [llvm] Add source file name for template instantiations in -ftime-trace (PR #98320)

2024-07-17 Thread Utkarsh Saxena via cfe-commits


@@ -3430,6 +3430,7 @@ Sema::InstantiateClass(SourceLocation 
PointOfInstantiation,
 llvm::raw_string_ostream OS(Name);

usx95 wrote:

I think we can do this on a need basis. Most source actions (like Parse*) 
already have this information (although not structured). See the unit test for 
examples.

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


[clang] [flang] [mlir] Add basic -mtune support (PR #98517)

2024-07-17 Thread David Spickett via cfe-commits

DavidSpickett wrote:

This was failing on our bots that build all backends, I've fixed that:
https://github.com/llvm/llvm-project/commit/8bf952d77fbe63f979e4293e95a5ca379e26eede

It will help you in future if you set an email address for your commits in this 
Github project. Buildbot will then use that to notify you of failures.

You can also glance at http://llvm.validation.linaro.org/ (the "Flang" section) 
or search flang in https://lab.llvm.org/buildbot/#/builders (not every one that 
includes flang, but all the ones that focus on it at least).

It will post on PRs too if it knows a single commit is the problem, but all the 
bots that would have been able to do that only build the AArch64 target and it 
worked fine in that case.

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


[clang] [llvm] Add source file name for template instantiations in -ftime-trace (PR #98320)

2024-07-17 Thread Utkarsh Saxena via cfe-commits

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

>From 03cc5fbebaf0c0c737e9304b8b3310ab4908fcaa Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 10 Jul 2024 13:52:46 +
Subject: [PATCH 1/8] Add an option to add source file info to -ftime-trace

---
 clang/include/clang/Driver/Options.td  | 4 
 clang/include/clang/Frontend/FrontendOptions.h | 3 +++
 clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 ++
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 ++
 4 files changed, 11 insertions(+)

diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index be7c3b60c20f1..c15f1b57bafc9 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3989,6 +3989,10 @@ def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, 
Group,
   HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory 
which will contain the JSON file">,
   Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
   MarshallingInfoString>;
+def ftime_trace_add_filename : Flag<["-"], "ftime-trace-add-filename">, 
Group,
+  HelpText<"Adds filename to event details wherever supported. Eg: For 
template instantiation A, details would include A@source_file.h.">,
+  Visibility<[ClangOption, CLOption, DXCOption]>;
+  MarshallingInfoString>;
 def fproc_stat_report : Joined<["-"], "fproc-stat-report">, Group,
   HelpText<"Print subprocess statistics">;
 def fproc_stat_report_EQ : Joined<["-"], "fproc-stat-report=">, Group,
diff --git a/clang/include/clang/Frontend/FrontendOptions.h 
b/clang/include/clang/Frontend/FrontendOptions.h
index 5e5034fe01eb5..019a6737f8129 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -583,6 +583,9 @@ class FrontendOptions {
   /// Path which stores the output files for -ftime-trace
   std::string TimeTracePath;
 
+  /// Adds filename to event details wherever supported
+  bool TimeTraceAddFilename = false;
+
   /// Output Path for module output file.
   std::string ModuleOutputPath;
 
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index a7bc6749c5852..f0fa7fd427906 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3430,6 +3430,8 @@ Sema::InstantiateClass(SourceLocation 
PointOfInstantiation,
 llvm::raw_string_ostream OS(Name);
 Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(),
 /*Qualified=*/true);
+if (llvm::timeTraceAddFilename())
+  OS << "@" << SourceMgr.getFilename(Instantiation->getLocation());
 return Name;
   });
 
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 88f6af80cbc55..ba55db4117c34 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4966,6 +4966,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation 
PointOfInstantiation,
 llvm::raw_string_ostream OS(Name);
 Function->getNameForDiagnostic(OS, getPrintingPolicy(),
/*Qualified=*/true);
+if (llvm::timeTraceAddFilename())
+  OS << "@" << SourceMgr.getFilename(Function->getLocation());
 return Name;
   });
 

>From ae991f8c88c21a0872a5fa63219b3cb9b2787d9a Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 10 Jul 2024 15:52:55 +
Subject: [PATCH 2/8] Add tests

---
 clang/include/clang/Driver/Options.td  |  4 
 clang/include/clang/Frontend/FrontendOptions.h |  3 ---
 clang/lib/Sema/SemaTemplateInstantiate.cpp |  3 +--
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp |  3 +--
 clang/test/Driver/ftime-trace-sections.py  | 16 +++-
 5 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index c15f1b57bafc9..be7c3b60c20f1 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3989,10 +3989,6 @@ def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, 
Group,
   HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory 
which will contain the JSON file">,
   Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
   MarshallingInfoString>;
-def ftime_trace_add_filename : Flag<["-"], "ftime-trace-add-filename">, 
Group,
-  HelpText<"Adds filename to event details wherever supported. Eg: For 
template instantiation A, details would include A@source_file.h.">,
-  Visibility<[ClangOption, CLOption, DXCOption]>;
-  MarshallingInfoString>;
 def fproc_stat_report : Joined<["-"], "fproc-stat-report">, Group,
   HelpText<"Print subprocess statistics">;
 def fproc_stat_report_EQ : Joined<["-"], "fproc-stat-report=">, Group,
diff --git a/clang/include/clang/Frontend/FrontendOptions.h 
b/clang/include/clang/Frontend/F

[clang] [clang] Implement P2582R1: CTAD from inherited constructors (PR #98788)

2024-07-17 Thread Haojian Wu via cfe-commits

hokein wrote:

Thanks for implementing it! 

I haven't looked into the implementation details yet.
Before doing so, I want to ensure I understand the standard correctly (the 
standard's wording is a bit hard to follow).

Per C++ 
[over.match.class.deduct#1.10](https://eel.is/c++draft/over.match.class.deduct#1.10):

> In addition, if C is defined and inherits constructors 
> ([[namespace.udecl]](https://eel.is/c++draft/namespace.udecl)) from a direct 
> base class denoted in the 
> [base-specifier-list](https://eel.is/c++draft/class.derived.general#nt:base-specifier-list)
>  by a 
> [class-or-decltype](https://eel.is/c++draft/class.derived.general#nt:class-or-decltype)
>  B, let A be an alias template whose template parameter list is that of C and 
> whose 
> [defining-type-id](https://eel.is/c++draft/dcl.name#nt:defining-type-id) is 
> B[.](https://eel.is/c++draft/over.match.class.deduct#1.sentence-7) If A is a 
> deducible template 
> ([[dcl.type.simple]](https://eel.is/c++draft/dcl.type.simple)), the set 
> contains the guides of A with the return type R of each guide replaced with 
> typename CC​::​type given a class template
template  class CC;
whose primary template is not defined and with a single partial specialization 
whose template parameter list is that of A and whose template argument list is 
a specialization of A with the template argument list of A 
([[temp.dep.type]](https://eel.is/c++draft/temp.dep.type)) having a member 
typedef type designating a template specialization with the template argument 
list of A but with C as the 
template[.](https://eel.is/c++draft/over.match.class.deduct#1.sentence-8)

Let's use the following example to illustrate:

```cpp
template  struct B {
  B(T1);
};
template  struct C : public B {
  using B::B;
};
```

Here, `C` is the struct `C`, and `B` is `B`.


### Steps:

1. **Find the inherited constructor for class `C`:** `B(T1)`.

2. **Synthesize an alias template `A`:** `template using A = 
B;`

3. **Check if `A` is a deducible template per 
https://eel.is/c++draft/dcl.type.simple#3:** here A is deducible

4. **Synthesize the deduction guide for `A`:** the one we have interests is 
`auto (T2) -> B(T2)`

5.  **Replace the return type with `CC>::type`:**

```cpp
template  class CC;

template 
class CC> {
public:
typedef C type;
};
```

The we get the final deduction guide for C: `auto (T2) -> CC>::type`;

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


[clang] [clang] Fix underlying type of EmbedExpr (PR #99050)

2024-07-17 Thread Mariya Podchishchaeva via cfe-commits

Fznamznon wrote:

I can add test with sizeof for sure, the problem is that it is already working 
https://godbolt.org/z/K69v8KPYa and we have similar ones in codebase already.
The test I'm struggling with is to check that elements in initializer list that 
are expanded from embed also have int type.


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


[clang] 72b3d7b - [clang][Interp] Makre sure we don't overflow Descriptor::AllocSize

2024-07-17 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-07-17T10:56:14+02:00
New Revision: 72b3d7bc87019ba7ef268ce322f90382f01b11af

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

LOG: [clang][Interp] Makre sure we don't overflow Descriptor::AllocSize

We allocate the metadata and the array elements in one allocation,
and we save its size in a field of type 'unsigned'. Makre sure the
full size of the allocation doesn't overflow the field.

Added: 


Modified: 
clang/lib/AST/Interp/Descriptor.cpp
clang/lib/AST/Interp/Descriptor.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Descriptor.cpp 
b/clang/lib/AST/Interp/Descriptor.cpp
index a3801a01688c8..f7d1201f625bb 100644
--- a/clang/lib/AST/Interp/Descriptor.cpp
+++ b/clang/lib/AST/Interp/Descriptor.cpp
@@ -303,6 +303,7 @@ Descriptor::Descriptor(const DeclTy &D, PrimType Type, 
MetadataSize MD,
   IsArray(true), CtorFn(getCtorArrayPrim(Type)),
   DtorFn(getDtorArrayPrim(Type)), MoveFn(getMoveArrayPrim(Type)) {
   assert(Source && "Missing source");
+  assert(NumElems <= (MaxArrayElemBytes / ElemSize));
 }
 
 /// Primitive unknown-size arrays.

diff  --git a/clang/lib/AST/Interp/Descriptor.h 
b/clang/lib/AST/Interp/Descriptor.h
index f444b8a78e802..0dd97812e5a5c 100644
--- a/clang/lib/AST/Interp/Descriptor.h
+++ b/clang/lib/AST/Interp/Descriptor.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_CLANG_AST_INTERP_DESCRIPTOR_H
 #define LLVM_CLANG_AST_INTERP_DESCRIPTOR_H
 
+#include "PrimType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 
@@ -125,6 +126,11 @@ struct Descriptor final {
   static constexpr MetadataSize InlineDescMD = sizeof(InlineDescriptor);
   static constexpr MetadataSize GlobalMD = sizeof(GlobalInlineDescriptor);
 
+  /// Maximum number of bytes to be used for array elements.
+  static constexpr unsigned MaxArrayElemBytes =
+  std::numeric_limits::max() - sizeof(InitMapPtr) -
+  align(std::max(*InlineDescMD, *GlobalMD));
+
   /// Pointer to the record, if block contains records.
   const Record *const ElemRecord = nullptr;
   /// Descriptor of the array element.



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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -14,6 +14,13 @@
 void free(void *);
 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
 
+void __attribute((ownership_returns(malloc1))) *my_malloc1(size_t);
+void __attribute((ownership_takes(malloc1, 1))) my_free1(void *);
+
+void __attribute((ownership_returns(malloc2))) *my_malloc2(size_t);
+void __attribute((ownership_returns(malloc2))) *my_malloc3(size_t);
+void __attribute((ownership_takes(malloc2, 1))) 
__attribute((ownership_takes(malloc3, 1))) my_free23(void *);

steakhal wrote:

To me, it would make more sense to allow at most one of this attribute to be 
present.

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -103,14 +103,46 @@ using namespace std::placeholders;
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
-enum AllocationFamily {
+enum AllocationFamilyKind {
   AF_None,
   AF_Malloc,
   AF_CXXNew,
   AF_CXXNewArray,
   AF_IfNameIndex,
   AF_Alloca,
-  AF_InnerBuffer
+  AF_InnerBuffer,
+  AF_Custom,
+};
+
+class AllocationFamily {
+public:
+  AllocationFamily(AllocationFamilyKind kind,

steakhal wrote:

I'd prefer having this explicit.

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


[clang] [clang][ASTImporter] Fix import of anonymous enums if multiple are present (PR #99281)

2024-07-17 Thread via cfe-commits

vabridgers wrote:

LGTM, pending integration tests, but someone else must approve. Thanks for 
following up on this!

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


[clang] 39d751a - [clang][Interp] Use an array root's field decl in the LValuePath

2024-07-17 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-07-17T11:26:50+02:00
New Revision: 39d751ad976ba9f5e8a1ad3880559faba38c3c3f

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

LOG: [clang][Interp] Use an array root's field decl in the LValuePath

Instead of pushing the index 0.

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/Pointer.cpp 
b/clang/lib/AST/Interp/Pointer.cpp
index b2e3a7ff70881..ff4da0fa805dc 100644
--- a/clang/lib/AST/Interp/Pointer.cpp
+++ b/clang/lib/AST/Interp/Pointer.cpp
@@ -152,8 +152,9 @@ APValue Pointer::toAPValue() const {
   Pointer Ptr = *this;
   while (Ptr.isField() || Ptr.isArrayElement()) {
 if (Ptr.isArrayRoot()) {
-Path.push_back(APValue::LValuePathEntry::ArrayIndex(0));
-Ptr = Ptr.getBase();
+  Path.push_back(APValue::LValuePathEntry(
+  {Ptr.getFieldDesc()->asDecl(), /*IsVirtual=*/false}));
+  Ptr = Ptr.getBase();
 } else if (Ptr.isArrayElement()) {
   if (Ptr.isOnePastEnd())
 
Path.push_back(APValue::LValuePathEntry::ArrayIndex(Ptr.getArray().getNumElems()));

diff  --git a/clang/test/AST/Interp/functions.cpp 
b/clang/test/AST/Interp/functions.cpp
index fa29e08a30175..f190262ad3ebe 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -644,3 +644,21 @@ namespace FunctionCast {
  // both-warning {{are a Clang extension}}
   int b[(int)IntFn(f)()];// ok
 }
+
+#if __cplusplus >= 202002L
+namespace StableAddress {
+  template struct str {
+char arr[N];
+  };
+  // FIXME: Deduction guide not needed with P1816R0.
+  template str(const char (&)[N]) -> str;
+
+  template constexpr int sum() {
+int n = 0;
+for (char c : s.arr)
+  n += c;
+return n;
+  }
+  static_assert(sum() == 1234, "");
+}
+#endif



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


[clang] [Concepts] Avoid substituting into constraints for invalid TemplateDecls (PR #75697)

2024-07-17 Thread Younan Zhang via cfe-commits


@@ -227,3 +227,20 @@ struct r6 {};
 
 using r6i = r6;
 // expected-error@-1 {{constraints not satisfied for class template 'r6' [with 
T = int]}}
+
+namespace GH73885 {
+
+template  // expected-error {{extraneous}}
+template  requires(T{})
+bool e_v = true;
+
+static_assert(e_v);
+
+// We do accept the following as an extension. See 
Sema::MatchTemplateParametersToScopeSpecifier()
+template <>  // expected-warning {{extraneous}}
+template  requires(T{true})
+constexpr bool e = true;

zyn0217 wrote:

This is brought by 
https://github.com/llvm/llvm-project/commit/65911498eff34ac4fc2f9c250efd49aa51c35f85,
 which I think is inappropriate nowadays but we probably need to keep it for 
... historical reasons?

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


[clang] [Concepts] Avoid substituting into constraints for invalid TemplateDecls (PR #75697)

2024-07-17 Thread Younan Zhang via cfe-commits


@@ -227,3 +227,20 @@ struct r6 {};
 
 using r6i = r6;
 // expected-error@-1 {{constraints not satisfied for class template 'r6' [with 
T = int]}}
+
+namespace GH73885 {
+
+template  // expected-error {{extraneous}}
+template  requires(T{})
+bool e_v = true;
+
+static_assert(e_v);
+
+// We do accept the following as an extension. See 
Sema::MatchTemplateParametersToScopeSpecifier()
+template <>  // expected-warning {{extraneous}}
+template  requires(T{true})
+constexpr bool e = true;

zyn0217 wrote:

https://github.com/llvm/llvm-project/issues/99296

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


[clang] [clang][ASTImporter] Fix import of anonymous enums if multiple are present (PR #99281)

2024-07-17 Thread Balázs Kéri via cfe-commits

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


[clang] [clang][driver] Support `--precompile` and `-fmodule-*` options in Clang-CL (PR #98761)

2024-07-17 Thread Sharadh Rajaraman via cfe-commits

https://github.com/sharadhr updated 
https://github.com/llvm/llvm-project/pull/98761

>From 1fed92a00f0d732a2575861c2bf6a6d053407255 Mon Sep 17 00:00:00 2001
From: Sharadh Rajaraman 
Date: Sat, 13 Jul 2024 19:25:47 +0100
Subject: [PATCH 1/7] Allow `--precompile` and `-fprebuilt-module-path` to be
 passed directly into CL driver without `/clang:` prefix

---
 clang/include/clang/Driver/Options.td | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 4ab8638175dd3..ca7cfef8453a0 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3085,7 +3085,7 @@ def fmodules_user_build_path : Separate<["-"], 
"fmodules-user-build-path">, Grou
   HelpText<"Specify the module user build path">,
   MarshallingInfoString>;
 def fprebuilt_module_path : Joined<["-"], "fprebuilt-module-path=">, 
Group,
-  Flags<[]>, Visibility<[ClangOption, CC1Option]>,
+  Flags<[]>, Visibility<[ClangOption, CLOption, CC1Option]>,
   MetaVarName<"">,
   HelpText<"Specify the prebuilt module path">;
 defm prebuilt_implicit_modules : BoolFOption<"prebuilt-implicit-modules",
@@ -5874,6 +5874,7 @@ def _output : Separate<["--"], "output">, Alias;
 def _param : Separate<["--"], "param">, Group;
 def _param_EQ : Joined<["--"], "param=">, Alias<_param>;
 def _precompile : Flag<["--"], "precompile">, Flags<[NoXarchOption]>,
+  Visibility<[ClangOption, CLOption]>,
   Group, HelpText<"Only precompile the input">;
 def _prefix_EQ : Joined<["--"], "prefix=">, Alias;
 def _prefix : Separate<["--"], "prefix">, Alias;

>From 182cff89e777b6f22d34fb074c79814e521a7a88 Mon Sep 17 00:00:00 2001
From: Sharadh Rajaraman 
Date: Sun, 14 Jul 2024 11:05:57 +0100
Subject: [PATCH 2/7] `TY_ModuleFile` should be a 'CXX' file type

---
 clang/lib/Driver/Types.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index a7b6b9000e1d2..c6a03f4491dd7 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -242,7 +242,7 @@ bool types::isCXX(ID Id) {
   case TY_CXXHUHeader:
   case TY_PP_CXXHeaderUnit:
   case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
-  case TY_CXXModule: case TY_PP_CXXModule:
+  case TY_CXXModule: case TY_PP_CXXModule: case TY_ModuleFile:
   case TY_PP_CLCXX:
   case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE:
   case TY_HIP:

>From 8daa27a9d45b85a55f180e5f84ae9b7fa8c11572 Mon Sep 17 00:00:00 2001
From: Sharadh Rajaraman 
Date: Sun, 14 Jul 2024 16:28:46 +0100
Subject: [PATCH 3/7] Support more `fmodule-*` options from CL driver

---
 clang/include/clang/Driver/Options.td | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index ca7cfef8453a0..bfe369a6284fe 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3094,11 +3094,11 @@ defm prebuilt_implicit_modules : 
BoolFOption<"prebuilt-implicit-modules",
   NegFlag, BothFlags<[], [ClangOption, CC1Option]>>;
 
 def fmodule_output_EQ : Joined<["-"], "fmodule-output=">,
-  Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option]>,
+  Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, CC1Option]>,
   MarshallingInfoString>,
   HelpText<"Save intermediate module file results when compiling a standard 
C++ module unit.">;
 def fmodule_output : Flag<["-"], "fmodule-output">, Flags<[NoXarchOption]>,
-  Visibility<[ClangOption, CC1Option]>,
+  Visibility<[ClangOption, CLOption, CC1Option]>,
   HelpText<"Save intermediate module file results when compiling a standard 
C++ module unit.">;
 
 defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf",
@@ -3278,8 +3278,10 @@ def fretain_comments_from_system_headers : Flag<["-"], 
"fretain-comments-from-sy
   Visibility<[ClangOption, CC1Option]>,
   MarshallingInfoFlag>;
 def fmodule_header : Flag <["-"], "fmodule-header">, Group,
+  Visibility<[ClangOption, CLOption]>,
   HelpText<"Build a C++20 Header Unit from a header">;
 def fmodule_header_EQ : Joined<["-"], "fmodule-header=">, Group,
+  Visibility<[ClangOption, CLOption]>,
   MetaVarName<"">,
   HelpText<"Build a C++20 Header Unit from a header that should be found in 
the user (fmodule-header=user) or system (fmodule-header=system) search path.">;
 

>From 865a8e57af0ede6f6d6ec60ebd837f6827019aec Mon Sep 17 00:00:00 2001
From: Sharadh Rajaraman <3754080+shara...@users.noreply.github.com>
Date: Tue, 16 Jul 2024 20:10:12 +0100
Subject: [PATCH 4/7] Resolve `clang-format` issues

---
 clang/lib/Driver/Types.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index c6a03f4491dd7..842eb59b7382d 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -242,7 +242,9 @@ bool types::isCXX(ID Id) {
   case TY_CXXHUHeader:
   case TY_P

[clang] [clang][driver] Support `--precompile` and `-fmodule-*` options in Clang-CL (PR #98761)

2024-07-17 Thread Sharadh Rajaraman via cfe-commits

https://github.com/sharadhr updated 
https://github.com/llvm/llvm-project/pull/98761

>From 1fed92a00f0d732a2575861c2bf6a6d053407255 Mon Sep 17 00:00:00 2001
From: Sharadh Rajaraman 
Date: Sat, 13 Jul 2024 19:25:47 +0100
Subject: [PATCH 1/5] Allow `--precompile` and `-fprebuilt-module-path` to be
 passed directly into CL driver without `/clang:` prefix

---
 clang/include/clang/Driver/Options.td | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 4ab8638175dd3..ca7cfef8453a0 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3085,7 +3085,7 @@ def fmodules_user_build_path : Separate<["-"], 
"fmodules-user-build-path">, Grou
   HelpText<"Specify the module user build path">,
   MarshallingInfoString>;
 def fprebuilt_module_path : Joined<["-"], "fprebuilt-module-path=">, 
Group,
-  Flags<[]>, Visibility<[ClangOption, CC1Option]>,
+  Flags<[]>, Visibility<[ClangOption, CLOption, CC1Option]>,
   MetaVarName<"">,
   HelpText<"Specify the prebuilt module path">;
 defm prebuilt_implicit_modules : BoolFOption<"prebuilt-implicit-modules",
@@ -5874,6 +5874,7 @@ def _output : Separate<["--"], "output">, Alias;
 def _param : Separate<["--"], "param">, Group;
 def _param_EQ : Joined<["--"], "param=">, Alias<_param>;
 def _precompile : Flag<["--"], "precompile">, Flags<[NoXarchOption]>,
+  Visibility<[ClangOption, CLOption]>,
   Group, HelpText<"Only precompile the input">;
 def _prefix_EQ : Joined<["--"], "prefix=">, Alias;
 def _prefix : Separate<["--"], "prefix">, Alias;

>From eda96d01d1e698b8f246cbbdb481356f67797260 Mon Sep 17 00:00:00 2001
From: Sharadh Rajaraman 
Date: Sun, 14 Jul 2024 16:28:46 +0100
Subject: [PATCH 2/5] Support more `fmodule-*` options from CL driver

---
 clang/include/clang/Driver/Options.td | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index ca7cfef8453a0..bfe369a6284fe 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3094,11 +3094,11 @@ defm prebuilt_implicit_modules : 
BoolFOption<"prebuilt-implicit-modules",
   NegFlag, BothFlags<[], [ClangOption, CC1Option]>>;
 
 def fmodule_output_EQ : Joined<["-"], "fmodule-output=">,
-  Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option]>,
+  Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, CC1Option]>,
   MarshallingInfoString>,
   HelpText<"Save intermediate module file results when compiling a standard 
C++ module unit.">;
 def fmodule_output : Flag<["-"], "fmodule-output">, Flags<[NoXarchOption]>,
-  Visibility<[ClangOption, CC1Option]>,
+  Visibility<[ClangOption, CLOption, CC1Option]>,
   HelpText<"Save intermediate module file results when compiling a standard 
C++ module unit.">;
 
 defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf",
@@ -3278,8 +3278,10 @@ def fretain_comments_from_system_headers : Flag<["-"], 
"fretain-comments-from-sy
   Visibility<[ClangOption, CC1Option]>,
   MarshallingInfoFlag>;
 def fmodule_header : Flag <["-"], "fmodule-header">, Group,
+  Visibility<[ClangOption, CLOption]>,
   HelpText<"Build a C++20 Header Unit from a header">;
 def fmodule_header_EQ : Joined<["-"], "fmodule-header=">, Group,
+  Visibility<[ClangOption, CLOption]>,
   MetaVarName<"">,
   HelpText<"Build a C++20 Header Unit from a header that should be found in 
the user (fmodule-header=user) or system (fmodule-header=system) search path.">;
 

>From 994ca23255888b14fe14c8abddb2d37eaa578ce3 Mon Sep 17 00:00:00 2001
From: Sharadh Rajaraman 
Date: Tue, 16 Jul 2024 23:49:08 +0100
Subject: [PATCH 3/5] `clang-cl` C++20 modules compile test

---
 clang/test/Driver/cl-cxx20-modules.cppm | 65 +
 1 file changed, 65 insertions(+)
 create mode 100644 clang/test/Driver/cl-cxx20-modules.cppm

diff --git a/clang/test/Driver/cl-cxx20-modules.cppm 
b/clang/test/Driver/cl-cxx20-modules.cppm
new file mode 100644
index 0..84807324b4cbc
--- /dev/null
+++ b/clang/test/Driver/cl-cxx20-modules.cppm
@@ -0,0 +1,65 @@
+// REQUIRES: system-windows
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cl /std:c++20 --precompile "%/t/Hello.cppm" "/Fo%/t/Hello.pcm"
+// RUN: %clang_cl /std:c++20 %/t/use.cpp -fmodule-file=Hello=%/t/Hello.pcm 
%/t/Hello.pcm /Fo%/t/SimpleHelloWorld.exe 2>&1
+
+// RUN: %/t/SimpleHelloWorld.exe
+// CHECK: Simple Hello World!
+
+//--- Hello.cppm
+module;
+#include 
+export module Hello;
+export void hello() {
+  std::cout << "Simple Hello World!\n";
+}
+
+//--- use.cpp
+import Hello;
+int main() {
+  hello();
+  return 0;
+}
+
+//--- M.cppm
+export module M;
+export import :interface_part;
+import :impl_part;
+export void Hello();
+
+//--- interface_part.cpp
+export module M:interface_part;
+export void World();
+
+//--- impl_part.cppm
+module;
+#inc

[clang] [clang][driver] Fix unused argument warning for `/std:c++20` for precompiled module inputs to `clang-cl` (PR #99300)

2024-07-17 Thread Sharadh Rajaraman via cfe-commits

https://github.com/sharadhr created 
https://github.com/llvm/llvm-project/pull/99300

Relates to #98761: `-fmodule-file` requires `/std:c++20` or greater, but 
passing that option results in an unused argument warning. This resolves that.

>From 11aaae5439b33ac636e8580b96d16b6d0d9dbd0a Mon Sep 17 00:00:00 2001
From: Sharadh Rajaraman 
Date: Sun, 14 Jul 2024 11:05:57 +0100
Subject: [PATCH 1/2] `TY_ModuleFile` should be a 'CXX' file type

---
 clang/lib/Driver/Types.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index a7b6b9000e1d2..c6a03f4491dd7 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -242,7 +242,7 @@ bool types::isCXX(ID Id) {
   case TY_CXXHUHeader:
   case TY_PP_CXXHeaderUnit:
   case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
-  case TY_CXXModule: case TY_PP_CXXModule:
+  case TY_CXXModule: case TY_PP_CXXModule: case TY_ModuleFile:
   case TY_PP_CLCXX:
   case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE:
   case TY_HIP:

>From fe0e22ae80572f8b084b94c80c8f27098b74d1a3 Mon Sep 17 00:00:00 2001
From: Sharadh Rajaraman <3754080+shara...@users.noreply.github.com>
Date: Tue, 16 Jul 2024 20:10:12 +0100
Subject: [PATCH 2/2] Resolve `clang-format` issues

---
 clang/lib/Driver/Types.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index c6a03f4491dd7..842eb59b7382d 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -242,7 +242,9 @@ bool types::isCXX(ID Id) {
   case TY_CXXHUHeader:
   case TY_PP_CXXHeaderUnit:
   case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
-  case TY_CXXModule: case TY_PP_CXXModule: case TY_ModuleFile:
+  case TY_CXXModule: 
+  case TY_PP_CXXModule:
+  case TY_ModuleFile:
   case TY_PP_CLCXX:
   case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE:
   case TY_HIP:

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


[clang] [clang][driver] Fix unused argument warning for `/std:c++20` for precompiled module inputs to `clang-cl` (PR #99300)

2024-07-17 Thread via cfe-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from 
other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

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


[clang] [clang][driver] Support `--precompile` and `-fmodule-*` options in Clang-CL (PR #98761)

2024-07-17 Thread Sharadh Rajaraman via cfe-commits


@@ -242,7 +242,7 @@ bool types::isCXX(ID Id) {
   case TY_CXXHUHeader:
   case TY_PP_CXXHeaderUnit:
   case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
-  case TY_CXXModule: case TY_PP_CXXModule:
+  case TY_CXXModule: case TY_PP_CXXModule: case TY_ModuleFile:

sharadhr wrote:

Commits have been moved to #99300. 

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


[clang] [clang][driver] Fix unused argument warning for `/std:c++20` for precompiled module inputs to `clang-cl` (PR #99300)

2024-07-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-driver

Author: Sharadh Rajaraman (sharadhr)


Changes

Relates to #98761: `-fmodule-file` requires `/std:c++20` or greater, 
but passing that option results in an unused argument warning. This resolves 
that.

---
Full diff: https://github.com/llvm/llvm-project/pull/99300.diff


1 Files Affected:

- (modified) clang/lib/Driver/Types.cpp (+3-1) 


``diff
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index a7b6b9000e1d2..842eb59b7382d 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -242,7 +242,9 @@ bool types::isCXX(ID Id) {
   case TY_CXXHUHeader:
   case TY_PP_CXXHeaderUnit:
   case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
-  case TY_CXXModule: case TY_PP_CXXModule:
+  case TY_CXXModule: 
+  case TY_PP_CXXModule:
+  case TY_ModuleFile:
   case TY_PP_CLCXX:
   case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE:
   case TY_HIP:

``




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


[clang] [clang][driver][clang-cl] Fix unused argument warning for `/std:c++20` for precompiled module inputs to `clang-cl` (PR #99300)

2024-07-17 Thread Sharadh Rajaraman via cfe-commits

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


[clang] [clang][driver][clang-cl] Support `--precompile` and `-fmodule-*` options in Clang-CL (PR #98761)

2024-07-17 Thread Sharadh Rajaraman via cfe-commits

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


[clang] [clang][driver][clang-cl] Fix unused argument warning for `/std:c++20` for precompiled module inputs to `clang-cl` (PR #99300)

2024-07-17 Thread Chuanqi Xu via cfe-commits

https://github.com/ChuanqiXu9 commented:

Please add a test for this too. We can use any file ends with `.pcm` to mimic  
module file in the Driver's test and we can use `CHECK-NOT:` to filter the 
warning.

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


[clang] [clang codegen] Emit int TBAA metadata on FP math libcall expf (PR #96025)

2024-07-17 Thread via cfe-commits

https://github.com/vfdff updated https://github.com/llvm/llvm-project/pull/96025

>From ece0662e3ca7086bbe4950660ad5b04be5a82055 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 
Date: Tue, 18 Jun 2024 09:21:07 -0400
Subject: [PATCH] [clang codegen] Emit int TBAA metadata on FP math libcall
 expf

Base on the discussion 
https://discourse.llvm.org/t/fp-can-we-add-pure-attribute-for-math-library-functions-default/79459,
math libcalls set errno, so it should emit "int" TBAA metadata on FP libcalls
to solve the alias issue.

Fix https://github.com/llvm/llvm-project/issues/86635
---
 clang/lib/CodeGen/CGBuiltin.cpp   | 29 ++-
 clang/test/CodeGen/math-libcalls-tbaa.cpp |  9 ---
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 67027f8aa93f3..aabe915321a98 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -688,7 +688,34 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const 
FunctionDecl *FD,
   const CallExpr *E, llvm::Constant *calleeValue) {
   CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
   CGCallee callee = CGCallee::forDirect(calleeValue, GlobalDecl(FD));
-  return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
+  RValue Call =
+  CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
+
+  // Check the supported intrinsic.
+  if (unsigned BuiltinID = FD->getBuiltinID()) {
+auto IntrinsicID = [&]() -> unsigned {
+  switch (BuiltinID) {
+  case Builtin::BIexpf:
+  case Builtin::BI__builtin_expf:
+  case Builtin::BI__builtin_expf128:
+return true;
+  }
+  // TODO: support more FP math libcalls
+  return false;
+}();
+
+// Restrict to target with errno, for example, MacOS doesn't set errno.
+if (IntrinsicID && CGF.CGM.getLangOpts().MathErrno &&
+!CGF.Builder.getIsFPConstrained()) {
+  ASTContext &Context = CGF.getContext();
+  // Emit "int" TBAA metadata on FP math libcalls.
+  clang::QualType IntTy = Context.IntTy;
+  TBAAAccessInfo TBAAInfo = CGF.CGM.getTBAAAccessInfo(IntTy);
+  Instruction *Inst = cast(Call.getScalarVal());
+  CGF.CGM.DecorateInstructionWithTBAA(Inst, TBAAInfo);
+}
+  }
+  return Call;
 }
 
 /// Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.*
diff --git a/clang/test/CodeGen/math-libcalls-tbaa.cpp 
b/clang/test/CodeGen/math-libcalls-tbaa.cpp
index 0b231d474df77..f15938dee0272 100644
--- a/clang/test/CodeGen/math-libcalls-tbaa.cpp
+++ b/clang/test/CodeGen/math-libcalls-tbaa.cpp
@@ -12,9 +12,8 @@ extern "C" float expf(float);
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:[[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], 
i64 40
 // CHECK-NEXT:[[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa 
[[TBAA2:![0-9]+]]
-// CHECK-NEXT:[[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) 
#[[ATTR2:[0-9]+]]
-// CHECK-NEXT:[[TMP1:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa 
[[TBAA2]]
-// CHECK-NEXT:[[MUL:%.*]] = fmul float [[CALL]], [[TMP1]]
+// CHECK-NEXT:[[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) 
#[[ATTR2:[0-9]+]], !tbaa [[TBAA6:![0-9]+]]
+// CHECK-NEXT:[[MUL:%.*]] = fmul float [[TMP0]], [[CALL]]
 // CHECK-NEXT:ret float [[MUL]]
 //
 extern "C" float foo (float num[], float r2inv, int n) {
@@ -27,11 +26,15 @@ extern "C" float foo (float num[], float r2inv, int n) {
 // NoNewStructPathTBAA: [[META3]] = !{!"float", [[META4:![0-9]+]], i64 0}
 // NoNewStructPathTBAA: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], 
i64 0}
 // NoNewStructPathTBAA: [[META5]] = !{!"Simple C++ TBAA"}
+// NoNewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0}
+// NoNewStructPathTBAA: [[META7]] = !{!"int", [[META4]], i64 0}
 //.
 // NewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0, i64 4}
 // NewStructPathTBAA: [[META3]] = !{[[META4:![0-9]+]], i64 4, !"float"}
 // NewStructPathTBAA: [[META4]] = !{[[META5:![0-9]+]], i64 1, !"omnipotent 
char"}
 // NewStructPathTBAA: [[META5]] = !{!"Simple C++ TBAA"}
+// NewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0, i64 4}
+// NewStructPathTBAA: [[META7]] = !{[[META4]], i64 4, !"int"}
 //.
  NOTE: These prefixes are unused and the list is autogenerated. Do not add 
tests below this line:
 // NewStructPathTBAA: {{.*}}

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


[clang] [Bounds Safety][NFC] Add `SemaBoundsSafety` class and move existing Sema checks there (PR #98954)

2024-07-17 Thread Dan Liew via cfe-commits

delcypher wrote:

> > As noted above `-fbounds-safety` **is a C language extension** which makes 
> > it seem like it would fit nicely into the existing division of Sema into 
> > multiple objects and relevant source files.
> 
> No, it doesn't fit nicely into the division, which is the reason we're having 
> this discussion.

If we don't agree on this then I must not fully understand what the criteria is 
for dividing Sema current is.
 
> You can have `SemaBoundsSafety.cpp` and your own "section" inside `Sema.h`, 
> like C++ features do (like templates or lambdas). There's no reason to make 
> separation physical by introducing `SemaBoundsSafety` class from the get-go.

I'm ok with this. Having the implementation in a separate file is where the 
main benefit lies. The separation into a separation into a separate class is a 
nice-to-have and ok to drop doing that.

> That's why I propose to follow long-established practice of doing 
> `SemaBoundsSafety.cpp`, and move that around later. What I'd like to evaluate 
> before deciding on `SemaBoundsChecking` is how big its interface is (what 
> would be exposed via `SemaBoundsChecking` class,)

Sure. Let's go with that approach then.



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


[clang] [clang] Extend lifetime analysis to support assignments for pointer-like objects. (PR #99032)

2024-07-17 Thread Haojian Wu via cfe-commits

https://github.com/hokein updated 
https://github.com/llvm/llvm-project/pull/99032

>From 9ac7a9543878fc93ea036cfa533c25bbbceeddf2 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Tue, 16 Jul 2024 12:29:35 +0200
Subject: [PATCH 1/2] [clang] Extend lifetime analysis to detect dangling
 assignments between pointer-like objects.

---
 clang/docs/ReleaseNotes.rst   |  3 ++
 clang/include/clang/Basic/DiagnosticGroups.td |  2 +
 .../clang/Basic/DiagnosticSemaKinds.td|  3 ++
 clang/lib/Sema/CheckExprLifetime.cpp  | 46 +--
 clang/lib/Sema/SemaOverload.cpp   |  9 ++--
 .../warn-lifetime-analysis-nocfg-disabled.cpp |  4 ++
 .../Sema/warn-lifetime-analysis-nocfg.cpp | 19 ++--
 clang/test/SemaCXX/warn-dangling-local.cpp|  4 +-
 8 files changed, 67 insertions(+), 23 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 969856a8f978c..26dcd54d65547 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -713,6 +713,9 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses integer constant expressions that are folded to a 
constant value as an extension in more circumstances. Fixes #GH59863
 
+- Clang now diagnoses dangling assignments for pointer-like objects (annotated 
with `[[gsl::Pointer]]`) under `-Wdangling-assignment-gsl` (off by default)
+  Fixes #GH63310.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 2241f8481484e..e0d97c6ce99db 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -449,6 +449,7 @@ def LogicalNotParentheses: 
DiagGroup<"logical-not-parentheses">;
 def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">;
 def OverloadedShiftOpParentheses: DiagGroup<"overloaded-shift-op-parentheses">;
 def DanglingAssignment: DiagGroup<"dangling-assignment">;
+def DanglingAssignmentGsl : DiagGroup<"dangling-assignment-gsl">;
 def DanglingElse: DiagGroup<"dangling-else">;
 def DanglingField : DiagGroup<"dangling-field">;
 def DanglingInitializerList : DiagGroup<"dangling-initializer-list">;
@@ -457,6 +458,7 @@ def ReturnStackAddress : DiagGroup<"return-stack-address">;
 // Name of this warning in GCC
 def : DiagGroup<"return-local-addr", [ReturnStackAddress]>;
 def Dangling : DiagGroup<"dangling", [DanglingAssignment,
+  DanglingAssignmentGsl,
   DanglingField,
   DanglingInitializerList,
   DanglingGsl,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 52ff4b026a60e..94e6d5c1322ce 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10121,6 +10121,9 @@ def warn_dangling_lifetime_pointer : Warning<
   "object backing the pointer "
   "will be destroyed at the end of the full-expression">,
   InGroup;
+def warn_dangling_lifetime_pointer_assignment : Warning<"object backing the "
+  "pointer %0 will be destroyed at the end of the full-expression">,
+  InGroup, DefaultIgnore;
 def warn_new_dangling_initializer_list : Warning<
   "array backing "
   "%select{initializer list subobject of the allocated object|"
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp 
b/clang/lib/Sema/CheckExprLifetime.cpp
index 995e4cbadacfe..ff32ef8c4a23c 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -191,7 +191,8 @@ struct IndirectLocalPathEntry {
 TemporaryCopy,
 LambdaCaptureInit,
 GslReferenceInit,
-GslPointerInit
+GslPointerInit,
+GslPointerAssignment,
   } Kind;
   Expr *E;
   union {
@@ -337,7 +338,8 @@ static void handleGslAnnotatedTypes(IndirectLocalPath 
&Path, Expr *Call,
   for (const IndirectLocalPathEntry &PE : llvm::reverse(Path)) {
 if (PE.Kind == IndirectLocalPathEntry::GslReferenceInit)
   continue;
-if (PE.Kind == IndirectLocalPathEntry::GslPointerInit)
+if (PE.Kind == IndirectLocalPathEntry::GslPointerInit ||
+PE.Kind == IndirectLocalPathEntry::GslPointerAssignment)
   return;
 break;
   }
@@ -937,6 +939,7 @@ static SourceRange nextPathEntryRange(const 
IndirectLocalPath &Path, unsigned I,
 case IndirectLocalPathEntry::TemporaryCopy:
 case IndirectLocalPathEntry::GslReferenceInit:
 case IndirectLocalPathEntry::GslPointerInit:
+case IndirectLocalPathEntry::GslPointerAssignment:
   // These exist primarily to mark the path as not permitting or
   // supporting lifetime extension.
   break;
@@ -966,7 +969,8 @@ static bool pathOnlyInitializesGslPointer(IndirectLocalPath 
&Path) {
 if (It.Kind == IndirectLocalPathEntry::LifetimeBoundCall)

[clang] [clang] Extend lifetime analysis to support assignments for pointer-like objects. (PR #99032)

2024-07-17 Thread Haojian Wu via cfe-commits

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


[clang] [clang] Extend lifetime analysis to support assignments for pointer-like objects. (PR #99032)

2024-07-17 Thread Haojian Wu via cfe-commits


@@ -966,7 +969,8 @@ static bool pathOnlyInitializesGslPointer(IndirectLocalPath 
&Path) {
 if (It.Kind == IndirectLocalPathEntry::LifetimeBoundCall)
   continue;
 return It.Kind == IndirectLocalPathEntry::GslPointerInit ||
-   It.Kind == IndirectLocalPathEntry::GslReferenceInit;
+   It.Kind == IndirectLocalPathEntry::GslReferenceInit ||

hokein wrote:

Done.

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


[clang] [clang] Extend lifetime analysis to support assignments for pointer-like objects. (PR #99032)

2024-07-17 Thread Haojian Wu via cfe-commits


@@ -1073,14 +1078,16 @@ static void checkExprLifetimeImpl(Sema &SemaRef,
 }
 
 case LK_Assignment: {
-  if (!MTE)
+  if (!MTE || pathContainsInit(Path))
 return false;
   assert(shouldLifetimeExtendThroughPath(Path) ==
  PathLifetimeKind::NoExtend &&
  "No lifetime extension for assignments");
-  if (!pathContainsInit(Path))
-SemaRef.Diag(DiagLoc, diag::warn_dangling_pointer_assignment)
-<< AEntity->LHS << DiagRange;
+  SemaRef.Diag(DiagLoc,
+   IsGslPtrInitWithGslTempOwner

hokein wrote:

Done, renamed to `IsGslPtrValueFromGslTempOwner`.

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


[clang] [clang] Extend lifetime analysis to support assignments for pointer-like objects. (PR #99032)

2024-07-17 Thread Haojian Wu via cfe-commits

https://github.com/hokein commented:

Thanks for the review.

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


[clang] [clang] Extend lifetime analysis to support assignments for pointer-like objects. (PR #99032)

2024-07-17 Thread Haojian Wu via cfe-commits


@@ -1284,16 +1294,26 @@ void checkExprLifetime(Sema &SemaRef, const 
InitializedEntity &Entity,
   auto LTResult = getEntityLifetime(&Entity);
   LifetimeKind LK = LTResult.getInt();
   const InitializedEntity *ExtendingEntity = LTResult.getPointer();
-  checkExprLifetimeImpl(SemaRef, &Entity, ExtendingEntity, LK, nullptr, Init);
+  bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored(
+  diag::warn_dangling_lifetime_pointer, SourceLocation());
+  checkExprLifetimeImpl(SemaRef, &Entity, ExtendingEntity, LK, nullptr, Init,

hokein wrote:

Done.

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


[clang] [clang] Extend lifetime analysis to support assignments for pointer-like objects. (PR #99032)

2024-07-17 Thread Haojian Wu via cfe-commits


@@ -1284,16 +1294,26 @@ void checkExprLifetime(Sema &SemaRef, const 
InitializedEntity &Entity,
   auto LTResult = getEntityLifetime(&Entity);
   LifetimeKind LK = LTResult.getInt();
   const InitializedEntity *ExtendingEntity = LTResult.getPointer();
-  checkExprLifetimeImpl(SemaRef, &Entity, ExtendingEntity, LK, nullptr, Init);
+  bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored(
+  diag::warn_dangling_lifetime_pointer, SourceLocation());
+  checkExprLifetimeImpl(SemaRef, &Entity, ExtendingEntity, LK, nullptr, Init,

hokein wrote:

We still need to run the code (not the gsl-specific part) even if we disable 
all dangling diagnostics. Because this code has the functionality that performs 
the lifetime extension when needed (see 
https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/CheckExprLifetime.cpp#L1043-L1045).

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


[clang] [clang] Extend lifetime analysis to support assignments for pointer-like objects. (PR #99032)

2024-07-17 Thread Haojian Wu via cfe-commits


@@ -966,7 +969,8 @@ static bool pathOnlyInitializesGslPointer(IndirectLocalPath 
&Path) {
 if (It.Kind == IndirectLocalPathEntry::LifetimeBoundCall)

hokein wrote:

Rewrote the `if` with the `switch`. 

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


[clang] [llvm] [openmp] [Clang][OpenMP] Add reverse directive (PR #92916)

2024-07-17 Thread Michael Kruse via cfe-commits


@@ -15749,6 +15757,186 @@ StmtResult 
SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses,
 buildPreInits(Context, PreInits));
 }
 
+StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
+   SourceLocation StartLoc,
+   SourceLocation EndLoc) {
+  ASTContext &Context = getASTContext();
+  Scope *CurScope = SemaRef.getCurScope();
+
+  // Empty statement should only be possible if there already was an error.
+  if (!AStmt)
+return StmtError();
+
+  constexpr unsigned NumLoops = 1;
+  Stmt *Body = nullptr;
+  SmallVector LoopHelpers(
+  NumLoops);
+  SmallVector, NumLoops + 1> OriginalInits;
+  if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers,
+  Body, OriginalInits))
+return StmtError();
+
+  // Delay applying the transformation to when template is completely
+  // instantiated.
+  if (SemaRef.CurContext->isDependentContext())
+return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
+   nullptr, nullptr);
+
+  assert(LoopHelpers.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  assert(OriginalInits.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
+
+  // Find the loop statement.
+  Stmt *LoopStmt = nullptr;
+  collectLoopStmts(AStmt, {LoopStmt});
+
+  // Determine the PreInit declarations.
+  SmallVector PreInits;
+  addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
+
+  auto *IterationVarRef = cast(LoopHelper.IterationVarRef);
+  QualType IVTy = IterationVarRef->getType();
+  uint64_t IVWidth = Context.getTypeSize(IVTy);
+  auto *OrigVar = cast(LoopHelper.Counters.front());
+
+  // Iteration variable SourceLocations.
+  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
+  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
+  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
+
+  // Locations pointing to the transformation.
+  SourceLocation TransformLoc = StartLoc;
+  SourceLocation TransformLocBegin = StartLoc;
+  SourceLocation TransformLocEnd = EndLoc;
+
+  // Internal variable names.
+  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
+  std::string TripCountName = (Twine(".tripcount.") + OrigVarName).str();
+  std::string ForwardIVName = (Twine(".forward.iv.") + OrigVarName).str();
+  std::string ReversedIVName = (Twine(".reversed.iv.") + OrigVarName).str();

Meinersbur wrote:

`Twine` stores a non-owning reference to its argument, here `OrigVarName`. If 
that string goes out of scope or is changed, that becomes a dangling reference. 
`Twine` was designed to be valid within a statement only; at the end of that 
statement temporaries may be released. From `Twine.h`:
```
  /// A Twine is not intended for use directly and should not be stored, its
  /// implementation relies on the ability to store pointers to temporary stack
  /// objects which may be deallocated at the end of a statement. Twines should
  /// only be used as const references in arguments, when an API wishes
  /// to accept possibly-concatenated strings.
```

In this case only two strings are concatenated, so there are no temporary 
strings that `Twine` could help avoiding. I may still have used `Twine` here 
because either I originally also appended a suffix, or expected `Twine` to 
benefit from being able to precompute the target string length. If that's the 
case, `std::string::operator+` should be able to do the same. Let me remove 
`Twine` here completely.

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


[clang] [llvm] [openmp] [Clang][OpenMP] Add reverse directive (PR #92916)

2024-07-17 Thread Alexey Bataev via cfe-commits


@@ -15749,6 +15757,186 @@ StmtResult 
SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses,
 buildPreInits(Context, PreInits));
 }
 
+StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
+   SourceLocation StartLoc,
+   SourceLocation EndLoc) {
+  ASTContext &Context = getASTContext();
+  Scope *CurScope = SemaRef.getCurScope();
+
+  // Empty statement should only be possible if there already was an error.
+  if (!AStmt)
+return StmtError();
+
+  constexpr unsigned NumLoops = 1;
+  Stmt *Body = nullptr;
+  SmallVector LoopHelpers(
+  NumLoops);
+  SmallVector, NumLoops + 1> OriginalInits;
+  if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers,
+  Body, OriginalInits))
+return StmtError();
+
+  // Delay applying the transformation to when template is completely
+  // instantiated.
+  if (SemaRef.CurContext->isDependentContext())
+return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
+   nullptr, nullptr);
+
+  assert(LoopHelpers.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  assert(OriginalInits.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
+
+  // Find the loop statement.
+  Stmt *LoopStmt = nullptr;
+  collectLoopStmts(AStmt, {LoopStmt});
+
+  // Determine the PreInit declarations.
+  SmallVector PreInits;
+  addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
+
+  auto *IterationVarRef = cast(LoopHelper.IterationVarRef);
+  QualType IVTy = IterationVarRef->getType();
+  uint64_t IVWidth = Context.getTypeSize(IVTy);
+  auto *OrigVar = cast(LoopHelper.Counters.front());
+
+  // Iteration variable SourceLocations.
+  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
+  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
+  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
+
+  // Locations pointing to the transformation.
+  SourceLocation TransformLoc = StartLoc;
+  SourceLocation TransformLocBegin = StartLoc;
+  SourceLocation TransformLocEnd = EndLoc;
+
+  // Internal variable names.
+  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
+  std::string TripCountName = (Twine(".tripcount.") + OrigVarName).str();
+  std::string ForwardIVName = (Twine(".forward.iv.") + OrigVarName).str();
+  std::string ReversedIVName = (Twine(".reversed.iv.") + OrigVarName).str();

alexey-bataev wrote:

Why not SmallString?

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


[clang] [flang] [flang] Add -rtlib flag (PR #99058)

2024-07-17 Thread David Truby via cfe-commits

https://github.com/DavidTruby updated 
https://github.com/llvm/llvm-project/pull/99058

>From 66e13f92a0680742b552fabde25df7752f8510c9 Mon Sep 17 00:00:00 2001
From: David Truby 
Date: Tue, 16 Jul 2024 15:39:28 +
Subject: [PATCH 1/3] [flang] Add -rtlib flag

This patch allows the -rtlib flag with flang-new to select between the
libgcc_s and compiler-rt runtimes. The behaviour is identical to the
same flag with clang.
---
 clang/include/clang/Driver/Options.td | 2 +-
 flang/test/Driver/linker-flags.f90| 6 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 234958f4eb382..c434fe64b3f53 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5621,7 +5621,7 @@ def resource_dir_EQ : Joined<["-"], "resource-dir=">, 
Flags<[NoXarchOption]>,
   Alias;
 def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>, Group,
   Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>;
-def rtlib_EQ : Joined<["-", "--"], "rtlib=">, Visibility<[ClangOption, 
CLOption]>,
+def rtlib_EQ : Joined<["-", "--"], "rtlib=">, Visibility<[ClangOption, 
CLOption, FlangOption]>,
   HelpText<"Compiler runtime library to use">;
 def frtlib_add_rpath: Flag<["-"], "frtlib-add-rpath">, 
Flags<[NoArgumentUnused]>,
   Visibility<[ClangOption, FlangOption]>,
diff --git a/flang/test/Driver/linker-flags.f90 
b/flang/test/Driver/linker-flags.f90
index 02e217494f818..25f1d6dcd8786 100644
--- a/flang/test/Driver/linker-flags.f90
+++ b/flang/test/Driver/linker-flags.f90
@@ -11,6 +11,7 @@
 ! RUN: %flang -### --target=x86_64-unknown-dragonfly %S/Inputs/hello.f90 2>&1 
| FileCheck %s --check-prefixes=CHECK,UNIX,UNIX-F128%f128-lib
 ! RUN: %flang -### --target=x86_64-unknown-haiku %S/Inputs/hello.f90 2>&1 | 
FileCheck %s --check-prefixes=CHECK,HAIKU,HAIKU-F128%f128-lib
 ! RUN: %flang -### --target=x86_64-windows-gnu %S/Inputs/hello.f90 2>&1 | 
FileCheck %s --check-prefixes=CHECK,MINGW,MINGW-F128%f128-lib
+! RUN: %flang -### -rtlib=compiler-rt --target=aarch64-linux-gnu 
%S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,UNIX,COMPILER-RT
 
 ! NOTE: Clang's driver library, clangDriver, usually adds 'oldnames' on 
Windows,
 !   but it is not needed when compiling Fortran code and they might bring 
in
@@ -27,12 +28,14 @@
 !   suffix. Clang's driver will try to resolve the path to the ld
 !   executable and may find the GNU linker from MinGW or Cygwin.
 ! UNIX-LABEL:  "{{.*}}ld{{(\.exe)?}}"
+! COMPILER-RT: "{{.*}}/clang_rt.crtbegin.o" 
 ! UNIX-SAME: "[[object_file]]"
 ! UNIX-F128NONE-NOT: FortranFloat128Math
 ! SOLARIS-F128NONE-NOT: FortranFloat128Math
 ! UNIX-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" 
"-lquadmath" "--no-as-needed"
 ! SOLARIS-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "-z" "ignore" 
"-lquadmath" "-z" "record"
 ! UNIX-SAME: "-lFortranRuntime" "-lFortranDecimal" "-lm"
+! COMPILER-RT: "{{.*}}/libclang_rt.builtins.a" "{{.*}}/clang_rt.crtend.o"
 
 ! DARWIN-LABEL:  "{{.*}}ld{{(\.exe)?}}"
 ! DARWIN-SAME: "[[object_file]]"
@@ -61,3 +64,6 @@
 ! MSVC-LABEL: link
 ! MSVC-SAME: /subsystem:console
 ! MSVC-SAME: "[[object_file]]"
+
+! COMPILER-RT-NOT: "-lgcc"
+! COMPILER-RT-NOT: "-lgcc_s"

>From 70dbdf25b5952d957133d1fa2f7b832b2359f43b Mon Sep 17 00:00:00 2001
From: David Truby 
Date: Tue, 16 Jul 2024 20:19:57 +
Subject: [PATCH 2/3] Remove clang_rt.crtbegin and clang_rt.crtend check

---
 flang/test/Driver/linker-flags.f90 | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/flang/test/Driver/linker-flags.f90 
b/flang/test/Driver/linker-flags.f90
index 25f1d6dcd8786..6b8957cdbcf3a 100644
--- a/flang/test/Driver/linker-flags.f90
+++ b/flang/test/Driver/linker-flags.f90
@@ -28,14 +28,13 @@
 !   suffix. Clang's driver will try to resolve the path to the ld
 !   executable and may find the GNU linker from MinGW or Cygwin.
 ! UNIX-LABEL:  "{{.*}}ld{{(\.exe)?}}"
-! COMPILER-RT: "{{.*}}/clang_rt.crtbegin.o" 
 ! UNIX-SAME: "[[object_file]]"
 ! UNIX-F128NONE-NOT: FortranFloat128Math
 ! SOLARIS-F128NONE-NOT: FortranFloat128Math
 ! UNIX-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" 
"-lquadmath" "--no-as-needed"
 ! SOLARIS-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "-z" "ignore" 
"-lquadmath" "-z" "record"
 ! UNIX-SAME: "-lFortranRuntime" "-lFortranDecimal" "-lm"
-! COMPILER-RT: "{{.*}}/libclang_rt.builtins.a" "{{.*}}/clang_rt.crtend.o"
+! COMPILER-RT: "{{.*}}/libclang_rt.builtins.a"
 
 ! DARWIN-LABEL:  "{{.*}}ld{{(\.exe)?}}"
 ! DARWIN-SAME: "[[object_file]]"

>From 878a9a9c0809930499920eb6197b469c71904d5e Mon Sep 17 00:00:00 2001
From: David Truby 
Date: Wed, 17 Jul 2024 11:00:59 +
Subject: [PATCH 3/3] Fix windows path (\\ vs /)

---
 flang/test/Driver/linker-flags.f90 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/test/Driver/linker-flags.f90 
b/flang/test/Driver/linker-flags.f90
index 6b89

[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Pavel Skripkin via cfe-commits


@@ -60,6 +67,41 @@ void testMalloc8() {
   operator delete[](p); // expected-warning{{Memory allocated by malloc() 
should be deallocated by free(), not operator delete[]}}
 }
 
+void testMalloc9() {
+  int *p = (int *)my_malloc(sizeof(int));
+  my_free(p); // no warning
+}
+
+void testMalloc10() {
+  int *p = (int *)my_malloc1(sizeof(int));
+  my_free1(p); // no warning
+}
+
+void testMalloc11() {
+  int *p = (int *)my_malloc2(sizeof(int));
+  my_free23(p); // no warning
+}
+
+void testMalloc12() {
+  int *p = (int *)my_malloc1(sizeof(int));
+  my_free(p); // expected-warning{{Memory allocated by my_malloc1() should be 
deallocated by function that takes ownership of 'malloc1', not my_free(), which 
takes ownership of 'malloc'}}

pskrgag wrote:

"malloc" and "malloc1" here means allocation classes (i.e. argument of 
`ownership_{returns,takes}`, so I decided to wrap them with quotes to make them 
look different from function names.

 Do you think it's worth wrapping function names as well?

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


[clang] [clang][driver][clang-cl] Support `--precompile` and `-fmodule-*` options in Clang-CL (PR #98761)

2024-07-17 Thread Sharadh Rajaraman via cfe-commits


@@ -0,0 +1,65 @@
+// REQUIRES: system-windows
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cl /std:c++20 --precompile "%/t/Hello.cppm" "/Fo%/t/Hello.pcm"

sharadhr wrote:

I've looked at the other tests but I don't quite follow how `-###` works—could 
you describe an example, please? Thanks!

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


[clang] 440fffa - [Clang][Concepts] Avoid substituting into constraints for invalid TemplateDecls (#75697)

2024-07-17 Thread via cfe-commits

Author: Younan Zhang
Date: 2024-07-17T19:17:01+08:00
New Revision: 440fffad7e7231fab766c6e00e47a39ad5a9b95e

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

LOG: [Clang][Concepts] Avoid substituting into constraints for invalid 
TemplateDecls (#75697)

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

Substituting into constraints for invalid TemplateDecls might still
yield dependent expressions and end up crashing later in evaluation.

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaConcept.cpp
clang/test/SemaTemplate/instantiate-requires-expr.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8c0d1635d2756..6dc45956a9afb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1042,6 +1042,7 @@ Bug Fixes to C++ Support
 - Fixed failed assertion when resolving context of defaulted comparison method 
outside of struct. (#GH96043).
 - Clang now diagnoses explicit object parameters in member pointers and other 
contexts where they should not appear.
   Fixes (#GH85992).
+- Fixed a crash-on-invalid bug involving extraneous template parameter with 
concept substitution. (#GH73885)
 
 Bug Fixes to AST Handling
 ^

diff  --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 84c5753a46ac3..9e16b67284be4 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -625,6 +625,12 @@ bool Sema::CheckConstraintSatisfaction(
 *this, nullptr, ConstraintExprs, ConvertedConstraints,
 TemplateArgsLists, TemplateIDRange, OutSatisfaction);
   }
+  // Invalid templates could make their way here. Substituting them could 
result
+  // in dependent expressions.
+  if (Template->isInvalidDecl()) {
+OutSatisfaction.IsSatisfied = false;
+return true;
+  }
 
   // A list of the template argument list flattened in a predictible manner for
   // the purposes of caching. The ConstraintSatisfaction type is in AST so it

diff  --git a/clang/test/SemaTemplate/instantiate-requires-expr.cpp 
b/clang/test/SemaTemplate/instantiate-requires-expr.cpp
index 516708bf4c875..20a19d731ae16 100644
--- a/clang/test/SemaTemplate/instantiate-requires-expr.cpp
+++ b/clang/test/SemaTemplate/instantiate-requires-expr.cpp
@@ -227,3 +227,13 @@ struct r6 {};
 
 using r6i = r6;
 // expected-error@-1 {{constraints not satisfied for class template 'r6' [with 
T = int]}}
+
+namespace GH73885 {
+
+template  // expected-error {{extraneous}}
+template  requires(T{})
+constexpr bool e_v = true;
+
+static_assert(e_v);
+
+} // namespace GH73885



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


[clang] [Concepts] Avoid substituting into constraints for invalid TemplateDecls (PR #75697)

2024-07-17 Thread Younan Zhang via cfe-commits

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


[clang] [llvm] [openmp] [Clang][OpenMP] Add reverse directive (PR #92916)

2024-07-17 Thread Michael Kruse via cfe-commits


@@ -15749,6 +15757,186 @@ StmtResult 
SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses,
 buildPreInits(Context, PreInits));
 }
 
+StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
+   SourceLocation StartLoc,
+   SourceLocation EndLoc) {
+  ASTContext &Context = getASTContext();
+  Scope *CurScope = SemaRef.getCurScope();
+
+  // Empty statement should only be possible if there already was an error.
+  if (!AStmt)
+return StmtError();
+
+  constexpr unsigned NumLoops = 1;
+  Stmt *Body = nullptr;
+  SmallVector LoopHelpers(
+  NumLoops);
+  SmallVector, NumLoops + 1> OriginalInits;
+  if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers,
+  Body, OriginalInits))
+return StmtError();
+
+  // Delay applying the transformation to when template is completely
+  // instantiated.
+  if (SemaRef.CurContext->isDependentContext())
+return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
+   nullptr, nullptr);
+
+  assert(LoopHelpers.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  assert(OriginalInits.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
+
+  // Find the loop statement.
+  Stmt *LoopStmt = nullptr;
+  collectLoopStmts(AStmt, {LoopStmt});
+
+  // Determine the PreInit declarations.
+  SmallVector PreInits;
+  addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
+
+  auto *IterationVarRef = cast(LoopHelper.IterationVarRef);
+  QualType IVTy = IterationVarRef->getType();
+  uint64_t IVWidth = Context.getTypeSize(IVTy);
+  auto *OrigVar = cast(LoopHelper.Counters.front());
+
+  // Iteration variable SourceLocations.
+  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
+  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
+  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
+
+  // Locations pointing to the transformation.
+  SourceLocation TransformLoc = StartLoc;
+  SourceLocation TransformLocBegin = StartLoc;
+  SourceLocation TransformLocEnd = EndLoc;
+
+  // Internal variable names.
+  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
+  std::string TripCountName = (Twine(".tripcount.") + OrigVarName).str();
+  std::string ForwardIVName = (Twine(".forward.iv.") + OrigVarName).str();
+  std::string ReversedIVName = (Twine(".reversed.iv.") + OrigVarName).str();
+
+  // LoopHelper.Updates will read the logical iteration number from
+  // LoopHelper.IterationVarRef, compute the value of the user loop counter of
+  // that logical iteration from it, then assign it to the user loop counter
+  // variable. We cannot directly use LoopHelper.IterationVarRef as the
+  // induction variable of the generated loop because it may cause an 
underflow:
+  // \code
+  //   for (unsigned i = 0; i < n; ++i)
+  // body(i);
+  // \endcode
+  //
+  // Naive reversal:
+  // \code
+  //   for (unsigned i = n-1; i >= 0; --i)
+  // body(i);
+  // \endcode
+  //
+  // Instead, we introduce a new iteration variable representing the logical
+  // iteration counter of the original loop, convert it to the logical 
iteration
+  // number of the reversed loop, then let LoopHelper.Updates compute the 
user's
+  // loop iteration variable from it.
+  // \code
+  //   for (auto .forward.iv = 0; .forward.iv < n; ++.forward.iv) {
+  // auto .reversed.iv = n - .forward.iv - 1;
+  // i = (.reversed.iv + 0) * 1;// LoopHelper.Updates
+  // body(i);   // Body
+  //   }
+  // \endcode
+
+  // Subexpressions with more than one use. One of the constraints of an AST is
+  // that every node object must appear at most once, hence we define a lambda
+  // that creates a new AST node at every use.
+  CaptureVars CopyTransformer(SemaRef);
+  auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
+return AssertSuccess(
+CopyTransformer.TransformExpr(LoopHelper.NumIterations));
+  };
+
+  // Create the iteration variable for the forward loop (from 0 to n-1).
+  VarDecl *ForwardIVDecl =
+  buildVarDecl(SemaRef, {}, IVTy, ForwardIVName, nullptr, OrigVar);
+  auto MakeForwardRef = [&SemaRef = this->SemaRef, ForwardIVDecl, IVTy,
+ OrigVarLoc]() {
+return buildDeclRefExpr(SemaRef, ForwardIVDecl, IVTy, OrigVarLoc);
+  };
+
+  // Iteration variable for the reversed induction variable (from n-1 downto 
0):
+  // Reuse the iteration variable created by checkOpenMPLoop.
+  auto *ReversedIVDecl = cast(IterationVarRef->getDecl());
+  ReversedIVDecl->setDeclName(
+  &SemaRef.PP.getIdentifierTable().get(ReversedIVName));
+
+  // For init-statement:
+  // \co

[clang] [llvm] [openmp] [Clang][OpenMP] Add reverse directive (PR #92916)

2024-07-17 Thread Alexey Bataev via cfe-commits


@@ -15749,6 +15757,186 @@ StmtResult 
SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses,
 buildPreInits(Context, PreInits));
 }
 
+StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
+   SourceLocation StartLoc,
+   SourceLocation EndLoc) {
+  ASTContext &Context = getASTContext();
+  Scope *CurScope = SemaRef.getCurScope();
+
+  // Empty statement should only be possible if there already was an error.
+  if (!AStmt)
+return StmtError();
+
+  constexpr unsigned NumLoops = 1;
+  Stmt *Body = nullptr;
+  SmallVector LoopHelpers(
+  NumLoops);
+  SmallVector, NumLoops + 1> OriginalInits;
+  if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers,
+  Body, OriginalInits))
+return StmtError();
+
+  // Delay applying the transformation to when template is completely
+  // instantiated.
+  if (SemaRef.CurContext->isDependentContext())
+return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
+   nullptr, nullptr);
+
+  assert(LoopHelpers.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  assert(OriginalInits.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
+
+  // Find the loop statement.
+  Stmt *LoopStmt = nullptr;
+  collectLoopStmts(AStmt, {LoopStmt});
+
+  // Determine the PreInit declarations.
+  SmallVector PreInits;
+  addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
+
+  auto *IterationVarRef = cast(LoopHelper.IterationVarRef);
+  QualType IVTy = IterationVarRef->getType();
+  uint64_t IVWidth = Context.getTypeSize(IVTy);
+  auto *OrigVar = cast(LoopHelper.Counters.front());
+
+  // Iteration variable SourceLocations.
+  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
+  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
+  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
+
+  // Locations pointing to the transformation.
+  SourceLocation TransformLoc = StartLoc;
+  SourceLocation TransformLocBegin = StartLoc;
+  SourceLocation TransformLocEnd = EndLoc;
+
+  // Internal variable names.
+  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
+  std::string TripCountName = (Twine(".tripcount.") + OrigVarName).str();
+  std::string ForwardIVName = (Twine(".forward.iv.") + OrigVarName).str();
+  std::string ReversedIVName = (Twine(".reversed.iv.") + OrigVarName).str();
+
+  // LoopHelper.Updates will read the logical iteration number from
+  // LoopHelper.IterationVarRef, compute the value of the user loop counter of
+  // that logical iteration from it, then assign it to the user loop counter
+  // variable. We cannot directly use LoopHelper.IterationVarRef as the
+  // induction variable of the generated loop because it may cause an 
underflow:
+  // \code
+  //   for (unsigned i = 0; i < n; ++i)
+  // body(i);
+  // \endcode
+  //
+  // Naive reversal:
+  // \code
+  //   for (unsigned i = n-1; i >= 0; --i)
+  // body(i);
+  // \endcode
+  //
+  // Instead, we introduce a new iteration variable representing the logical
+  // iteration counter of the original loop, convert it to the logical 
iteration
+  // number of the reversed loop, then let LoopHelper.Updates compute the 
user's
+  // loop iteration variable from it.
+  // \code
+  //   for (auto .forward.iv = 0; .forward.iv < n; ++.forward.iv) {
+  // auto .reversed.iv = n - .forward.iv - 1;
+  // i = (.reversed.iv + 0) * 1;// LoopHelper.Updates
+  // body(i);   // Body
+  //   }
+  // \endcode
+
+  // Subexpressions with more than one use. One of the constraints of an AST is
+  // that every node object must appear at most once, hence we define a lambda
+  // that creates a new AST node at every use.
+  CaptureVars CopyTransformer(SemaRef);
+  auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
+return AssertSuccess(
+CopyTransformer.TransformExpr(LoopHelper.NumIterations));
+  };
+
+  // Create the iteration variable for the forward loop (from 0 to n-1).
+  VarDecl *ForwardIVDecl =
+  buildVarDecl(SemaRef, {}, IVTy, ForwardIVName, nullptr, OrigVar);
+  auto MakeForwardRef = [&SemaRef = this->SemaRef, ForwardIVDecl, IVTy,
+ OrigVarLoc]() {
+return buildDeclRefExpr(SemaRef, ForwardIVDecl, IVTy, OrigVarLoc);
+  };
+
+  // Iteration variable for the reversed induction variable (from n-1 downto 
0):
+  // Reuse the iteration variable created by checkOpenMPLoop.
+  auto *ReversedIVDecl = cast(IterationVarRef->getDecl());
+  ReversedIVDecl->setDeclName(
+  &SemaRef.PP.getIdentifierTable().get(ReversedIVName));
+
+  // For init-statement:
+  // \co

[clang] [Clang] fix assertion failure in invalid delete operator declaration check (PR #99308)

2024-07-17 Thread Oleksandr T. via cfe-commits

https://github.com/a-tarasyuk created 
https://github.com/llvm/llvm-project/pull/99308

Fixes #96191

>From 39de759ac60f2f06953ebe32392c25837ba591f1 Mon Sep 17 00:00:00 2001
From: Oleksandr T 
Date: Wed, 17 Jul 2024 14:21:31 +0300
Subject: [PATCH] [Clang] fix assertion failure in invalid delete operator
 declaration check

---
 clang/docs/ReleaseNotes.rst| 1 +
 clang/lib/Sema/SemaExprCXX.cpp | 3 +++
 clang/test/SemaCXX/cxx2a-destroying-delete.cpp | 9 +
 3 files changed, 13 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6dc45956a9afb..ed99f3796ad34 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1043,6 +1043,7 @@ Bug Fixes to C++ Support
 - Clang now diagnoses explicit object parameters in member pointers and other 
contexts where they should not appear.
   Fixes (#GH85992).
 - Fixed a crash-on-invalid bug involving extraneous template parameter with 
concept substitution. (#GH73885)
+- Fixed a failed assertion when checking invalid delete operator declaration 
(GH96191).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index bef7da239e6e5..c581a3448e927 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3806,6 +3806,9 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool 
UseGlobal,
  Overaligned, DeleteName);
 }
 
+if (OperatorDelete->isInvalidDecl())
+  return ExprError();
+
 MarkFunctionReferenced(StartLoc, OperatorDelete);
 
 // Check access and ambiguity of destructor if we're going to call it.
diff --git a/clang/test/SemaCXX/cxx2a-destroying-delete.cpp 
b/clang/test/SemaCXX/cxx2a-destroying-delete.cpp
index 349e6e9538a4c..25b985ef11d15 100644
--- a/clang/test/SemaCXX/cxx2a-destroying-delete.cpp
+++ b/clang/test/SemaCXX/cxx2a-destroying-delete.cpp
@@ -187,3 +187,12 @@ namespace delete_from_new {
 #endif
   }
 }
+
+namespace GH96191 {
+  struct S {};
+  struct T {
+void operator delete(S) { } // expected-error {{first parameter of 
'operator delete' must have type 'void *'}}
+  };
+
+  void foo(T *t) { delete t; }
+}

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


[clang] [Clang] fix assertion failure in invalid delete operator declaration check (PR #99308)

2024-07-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Oleksandr T. (a-tarasyuk)


Changes

Fixes #96191

---
Full diff: https://github.com/llvm/llvm-project/pull/99308.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/Sema/SemaExprCXX.cpp (+3) 
- (modified) clang/test/SemaCXX/cxx2a-destroying-delete.cpp (+9) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6dc45956a9afb..ed99f3796ad34 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1043,6 +1043,7 @@ Bug Fixes to C++ Support
 - Clang now diagnoses explicit object parameters in member pointers and other 
contexts where they should not appear.
   Fixes (#GH85992).
 - Fixed a crash-on-invalid bug involving extraneous template parameter with 
concept substitution. (#GH73885)
+- Fixed a failed assertion when checking invalid delete operator declaration 
(GH96191).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index bef7da239e6e5..c581a3448e927 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3806,6 +3806,9 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool 
UseGlobal,
  Overaligned, DeleteName);
 }
 
+if (OperatorDelete->isInvalidDecl())
+  return ExprError();
+
 MarkFunctionReferenced(StartLoc, OperatorDelete);
 
 // Check access and ambiguity of destructor if we're going to call it.
diff --git a/clang/test/SemaCXX/cxx2a-destroying-delete.cpp 
b/clang/test/SemaCXX/cxx2a-destroying-delete.cpp
index 349e6e9538a4c..25b985ef11d15 100644
--- a/clang/test/SemaCXX/cxx2a-destroying-delete.cpp
+++ b/clang/test/SemaCXX/cxx2a-destroying-delete.cpp
@@ -187,3 +187,12 @@ namespace delete_from_new {
 #endif
   }
 }
+
+namespace GH96191 {
+  struct S {};
+  struct T {
+void operator delete(S) { } // expected-error {{first parameter of 
'operator delete' must have type 'void *'}}
+  };
+
+  void foo(T *t) { delete t; }
+}

``




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


[clang] [Clang][NEON] Add neon target guard to intrinsics (PR #98624)

2024-07-17 Thread Maciej Gabka via cfe-commits


@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +dotprod  
-target-feature +fullfp16 -target-feature +fp16fml -target-feature +i8mm 
-target-feature +bf16 -verify -emit-llvm -o - %s
+
+// This test is testing the diagnostics that Clang emits when compiling 
without '+neon'.

mgabka wrote:

do we have a positive Sema tests to show that the intrinsics are available when 
the neon feature is present?

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


[clang] [Clang SA]: add support for mismatched ownership_returns+ownership_takes calls for custom allocation classes (PR #98941)

2024-07-17 Thread Balazs Benics via cfe-commits


@@ -60,6 +67,41 @@ void testMalloc8() {
   operator delete[](p); // expected-warning{{Memory allocated by malloc() 
should be deallocated by free(), not operator delete[]}}
 }
 
+void testMalloc9() {
+  int *p = (int *)my_malloc(sizeof(int));
+  my_free(p); // no warning
+}
+
+void testMalloc10() {
+  int *p = (int *)my_malloc1(sizeof(int));
+  my_free1(p); // no warning
+}
+
+void testMalloc11() {
+  int *p = (int *)my_malloc2(sizeof(int));
+  my_free23(p); // no warning
+}
+
+void testMalloc12() {
+  int *p = (int *)my_malloc1(sizeof(int));
+  my_free(p); // expected-warning{{Memory allocated by my_malloc1() should be 
deallocated by function that takes ownership of 'malloc1', not my_free(), which 
takes ownership of 'malloc'}}

steakhal wrote:

Ah, I see. The phrasing wasn't clear to me. Maybe because we don't have a clear 
spec for this attribute, thus it's difficult to make out things that have 
special meaning.
I think we should quote function names, yes.

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


[clang] [llvm] [openmp] [Clang][OpenMP] Add reverse directive (PR #92916)

2024-07-17 Thread Michael Kruse via cfe-commits


@@ -15749,6 +15757,186 @@ StmtResult 
SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses,
 buildPreInits(Context, PreInits));
 }
 
+StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
+   SourceLocation StartLoc,
+   SourceLocation EndLoc) {
+  ASTContext &Context = getASTContext();
+  Scope *CurScope = SemaRef.getCurScope();
+
+  // Empty statement should only be possible if there already was an error.
+  if (!AStmt)
+return StmtError();
+
+  constexpr unsigned NumLoops = 1;
+  Stmt *Body = nullptr;
+  SmallVector LoopHelpers(
+  NumLoops);
+  SmallVector, NumLoops + 1> OriginalInits;
+  if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers,
+  Body, OriginalInits))
+return StmtError();
+
+  // Delay applying the transformation to when template is completely
+  // instantiated.
+  if (SemaRef.CurContext->isDependentContext())
+return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
+   nullptr, nullptr);
+
+  assert(LoopHelpers.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  assert(OriginalInits.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
+
+  // Find the loop statement.
+  Stmt *LoopStmt = nullptr;
+  collectLoopStmts(AStmt, {LoopStmt});
+
+  // Determine the PreInit declarations.
+  SmallVector PreInits;
+  addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
+
+  auto *IterationVarRef = cast(LoopHelper.IterationVarRef);
+  QualType IVTy = IterationVarRef->getType();
+  uint64_t IVWidth = Context.getTypeSize(IVTy);
+  auto *OrigVar = cast(LoopHelper.Counters.front());
+
+  // Iteration variable SourceLocations.
+  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
+  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
+  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
+
+  // Locations pointing to the transformation.
+  SourceLocation TransformLoc = StartLoc;
+  SourceLocation TransformLocBegin = StartLoc;
+  SourceLocation TransformLocEnd = EndLoc;
+
+  // Internal variable names.
+  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
+  std::string TripCountName = (Twine(".tripcount.") + OrigVarName).str();
+  std::string ForwardIVName = (Twine(".forward.iv.") + OrigVarName).str();
+  std::string ReversedIVName = (Twine(".reversed.iv.") + OrigVarName).str();
+
+  // LoopHelper.Updates will read the logical iteration number from
+  // LoopHelper.IterationVarRef, compute the value of the user loop counter of
+  // that logical iteration from it, then assign it to the user loop counter
+  // variable. We cannot directly use LoopHelper.IterationVarRef as the
+  // induction variable of the generated loop because it may cause an 
underflow:
+  // \code
+  //   for (unsigned i = 0; i < n; ++i)
+  // body(i);
+  // \endcode
+  //
+  // Naive reversal:
+  // \code
+  //   for (unsigned i = n-1; i >= 0; --i)
+  // body(i);
+  // \endcode
+  //
+  // Instead, we introduce a new iteration variable representing the logical
+  // iteration counter of the original loop, convert it to the logical 
iteration
+  // number of the reversed loop, then let LoopHelper.Updates compute the 
user's
+  // loop iteration variable from it.
+  // \code
+  //   for (auto .forward.iv = 0; .forward.iv < n; ++.forward.iv) {
+  // auto .reversed.iv = n - .forward.iv - 1;
+  // i = (.reversed.iv + 0) * 1;// LoopHelper.Updates
+  // body(i);   // Body
+  //   }
+  // \endcode
+
+  // Subexpressions with more than one use. One of the constraints of an AST is
+  // that every node object must appear at most once, hence we define a lambda
+  // that creates a new AST node at every use.
+  CaptureVars CopyTransformer(SemaRef);
+  auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
+return AssertSuccess(
+CopyTransformer.TransformExpr(LoopHelper.NumIterations));
+  };
+
+  // Create the iteration variable for the forward loop (from 0 to n-1).
+  VarDecl *ForwardIVDecl =
+  buildVarDecl(SemaRef, {}, IVTy, ForwardIVName, nullptr, OrigVar);
+  auto MakeForwardRef = [&SemaRef = this->SemaRef, ForwardIVDecl, IVTy,
+ OrigVarLoc]() {
+return buildDeclRefExpr(SemaRef, ForwardIVDecl, IVTy, OrigVarLoc);
+  };
+
+  // Iteration variable for the reversed induction variable (from n-1 downto 
0):
+  // Reuse the iteration variable created by checkOpenMPLoop.
+  auto *ReversedIVDecl = cast(IterationVarRef->getDecl());
+  ReversedIVDecl->setDeclName(
+  &SemaRef.PP.getIdentifierTable().get(ReversedIVName));
+
+  // For init-statement:
+  // \co

[clang] [clang][NFC] Move more functions from `Sema` to `SemaObjC` (PR #97172)

2024-07-17 Thread Vlad Serebrennikov via cfe-commits

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


[clang] [libc] [libcxx] [libc][libcxx] Support for building libc++ against LLVM libc (PR #99287)

2024-07-17 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 commented:

I was just about to do something similar, so I'm glad you got to it before me.

I think we'll need a CMake check on whether or not `libc` was enabled as a 
runtime if this option is enabled in `libcxx`, but beyond that it looks very 
reasonable. All we're doing is suppressing the system includes with 
`-nostdlibinc` and then adding an interface include to the `libc` targets.

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


[clang] [llvm] [openmp] [Clang][OpenMP] Add reverse directive (PR #92916)

2024-07-17 Thread Alexey Bataev via cfe-commits


@@ -15749,6 +15757,186 @@ StmtResult 
SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses,
 buildPreInits(Context, PreInits));
 }
 
+StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
+   SourceLocation StartLoc,
+   SourceLocation EndLoc) {
+  ASTContext &Context = getASTContext();
+  Scope *CurScope = SemaRef.getCurScope();
+
+  // Empty statement should only be possible if there already was an error.
+  if (!AStmt)
+return StmtError();
+
+  constexpr unsigned NumLoops = 1;
+  Stmt *Body = nullptr;
+  SmallVector LoopHelpers(
+  NumLoops);
+  SmallVector, NumLoops + 1> OriginalInits;
+  if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers,
+  Body, OriginalInits))
+return StmtError();
+
+  // Delay applying the transformation to when template is completely
+  // instantiated.
+  if (SemaRef.CurContext->isDependentContext())
+return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
+   nullptr, nullptr);
+
+  assert(LoopHelpers.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  assert(OriginalInits.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
+
+  // Find the loop statement.
+  Stmt *LoopStmt = nullptr;
+  collectLoopStmts(AStmt, {LoopStmt});
+
+  // Determine the PreInit declarations.
+  SmallVector PreInits;
+  addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
+
+  auto *IterationVarRef = cast(LoopHelper.IterationVarRef);
+  QualType IVTy = IterationVarRef->getType();
+  uint64_t IVWidth = Context.getTypeSize(IVTy);
+  auto *OrigVar = cast(LoopHelper.Counters.front());
+
+  // Iteration variable SourceLocations.
+  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
+  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
+  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
+
+  // Locations pointing to the transformation.
+  SourceLocation TransformLoc = StartLoc;
+  SourceLocation TransformLocBegin = StartLoc;
+  SourceLocation TransformLocEnd = EndLoc;
+
+  // Internal variable names.
+  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
+  std::string TripCountName = (Twine(".tripcount.") + OrigVarName).str();
+  std::string ForwardIVName = (Twine(".forward.iv.") + OrigVarName).str();
+  std::string ReversedIVName = (Twine(".reversed.iv.") + OrigVarName).str();
+
+  // LoopHelper.Updates will read the logical iteration number from
+  // LoopHelper.IterationVarRef, compute the value of the user loop counter of
+  // that logical iteration from it, then assign it to the user loop counter
+  // variable. We cannot directly use LoopHelper.IterationVarRef as the
+  // induction variable of the generated loop because it may cause an 
underflow:
+  // \code
+  //   for (unsigned i = 0; i < n; ++i)
+  // body(i);
+  // \endcode
+  //
+  // Naive reversal:
+  // \code
+  //   for (unsigned i = n-1; i >= 0; --i)
+  // body(i);
+  // \endcode
+  //
+  // Instead, we introduce a new iteration variable representing the logical
+  // iteration counter of the original loop, convert it to the logical 
iteration
+  // number of the reversed loop, then let LoopHelper.Updates compute the 
user's
+  // loop iteration variable from it.
+  // \code
+  //   for (auto .forward.iv = 0; .forward.iv < n; ++.forward.iv) {
+  // auto .reversed.iv = n - .forward.iv - 1;
+  // i = (.reversed.iv + 0) * 1;// LoopHelper.Updates
+  // body(i);   // Body
+  //   }
+  // \endcode
+
+  // Subexpressions with more than one use. One of the constraints of an AST is
+  // that every node object must appear at most once, hence we define a lambda
+  // that creates a new AST node at every use.
+  CaptureVars CopyTransformer(SemaRef);
+  auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
+return AssertSuccess(
+CopyTransformer.TransformExpr(LoopHelper.NumIterations));
+  };
+
+  // Create the iteration variable for the forward loop (from 0 to n-1).
+  VarDecl *ForwardIVDecl =
+  buildVarDecl(SemaRef, {}, IVTy, ForwardIVName, nullptr, OrigVar);
+  auto MakeForwardRef = [&SemaRef = this->SemaRef, ForwardIVDecl, IVTy,
+ OrigVarLoc]() {
+return buildDeclRefExpr(SemaRef, ForwardIVDecl, IVTy, OrigVarLoc);
+  };
+
+  // Iteration variable for the reversed induction variable (from n-1 downto 
0):
+  // Reuse the iteration variable created by checkOpenMPLoop.
+  auto *ReversedIVDecl = cast(IterationVarRef->getDecl());
+  ReversedIVDecl->setDeclName(
+  &SemaRef.PP.getIdentifierTable().get(ReversedIVName));
+
+  // For init-statement:
+  // \co

[clang] [clang][Sema] Resolving Inconsistent Arguments Panic in Variadic Template Variables (PR #70280)

2024-07-17 Thread via cfe-commits

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


[clang] [clang][Sema] Resolving Inconsistent Arguments Panic in Variadic Template Variables (PR #70280)

2024-07-17 Thread via cfe-commits

cor3ntin wrote:

Fixed by 
https://github.com/llvm/llvm-project/commit/7a28a5b3fee6c78ad59af79a3d03c00db153c49f

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


[clang] [Clang] Implement CWG2351 `void{}` (PR #78060)

2024-07-17 Thread via cfe-commits

cor3ntin wrote:

@MitalAshok feel free to merge in ~2 days if you don't hear back from @shafik 

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


[clang] [Clang] Reuse tail-padding for more types that are not POD for the purpose of layout (PR #90462)

2024-07-17 Thread via cfe-commits

cor3ntin wrote:

@MitalAshok ping

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


[clang] [Clang] Fix some assertions not looking through type sugar (PR #92299)

2024-07-17 Thread via cfe-commits

cor3ntin wrote:

@MitalAshok ping

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


[clang] [Clang] [C23] Fix typeof_unqual for qualified array types (PR #92767)

2024-07-17 Thread via cfe-commits

cor3ntin wrote:

@MitalAshok ping

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


[clang] [Clang][Sema] Fix qualifier restriction of overriden methods (PR #71696)

2024-07-17 Thread via cfe-commits

cor3ntin wrote:

@ecnelises are you still working on that?

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


[clang] bc8a8f5 - [clang][Sema] Improve `Sema::CheckCXXDefaultArguments` (#97338)

2024-07-17 Thread via cfe-commits

Author: MagentaTreehouse
Date: 2024-07-17T14:09:35+02:00
New Revision: bc8a8f5415c522f99600171e012d511c010d7309

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

LOG: [clang][Sema] Improve `Sema::CheckCXXDefaultArguments` (#97338)

In the second loop in `Sema::CheckCXXDefaultArguments`, we don't need to
re-examine the first parameter with a default argument. Dropped the
first iteration of that loop.

In addition, use the preferred early `continue` for the if-statement in
the loop.

Added: 


Modified: 
clang/lib/Sema/SemaDeclCXX.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index f24912cde275a..2bfb103e8953d 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1630,9 +1630,6 @@ void Sema::MergeVarDeclExceptionSpecs(VarDecl *New, 
VarDecl *Old) {
 /// function declaration are well-formed according to C++
 /// [dcl.fct.default].
 void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
-  unsigned NumParams = FD->getNumParams();
-  unsigned ParamIdx = 0;
-
   // This checking doesn't make sense for explicit specializations; their
   // default arguments are determined by the declaration we're specializing,
   // not by FD.
@@ -1642,6 +1639,9 @@ void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
 if (FTD->isMemberSpecialization())
   return;
 
+  unsigned NumParams = FD->getNumParams();
+  unsigned ParamIdx = 0;
+
   // Find first parameter with a default argument
   for (; ParamIdx < NumParams; ++ParamIdx) {
 ParmVarDecl *Param = FD->getParamDecl(ParamIdx);
@@ -1654,21 +1654,19 @@ void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
   //   with a default argument shall have a default argument supplied in this 
or
   //   a previous declaration, unless the parameter was expanded from a
   //   parameter pack, or shall be a function parameter pack.
-  for (; ParamIdx < NumParams; ++ParamIdx) {
+  for (++ParamIdx; ParamIdx < NumParams; ++ParamIdx) {
 ParmVarDecl *Param = FD->getParamDecl(ParamIdx);
-if (!Param->hasDefaultArg() && !Param->isParameterPack() &&
-!(CurrentInstantiationScope &&
-  CurrentInstantiationScope->isLocalPackExpansion(Param))) {
-  if (Param->isInvalidDecl())
-/* We already complained about this parameter. */;
-  else if (Param->getIdentifier())
-Diag(Param->getLocation(),
- diag::err_param_default_argument_missing_name)
+if (Param->hasDefaultArg() || Param->isParameterPack() ||
+(CurrentInstantiationScope &&
+ CurrentInstantiationScope->isLocalPackExpansion(Param)))
+  continue;
+if (Param->isInvalidDecl())
+  /* We already complained about this parameter. */;
+else if (Param->getIdentifier())
+  Diag(Param->getLocation(), diag::err_param_default_argument_missing_name)
   << Param->getIdentifier();
-  else
-Diag(Param->getLocation(),
- diag::err_param_default_argument_missing);
-}
+else
+  Diag(Param->getLocation(), diag::err_param_default_argument_missing);
   }
 }
 



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


[clang] [clang][Sema] Improve `Sema::CheckCXXDefaultArguments` (PR #97338)

2024-07-17 Thread via cfe-commits

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


[clang] [Clang] Warn with -Wpre-c23-compat instead of -Wpre-c++17-compat for u8 character literals in C23 (PR #97210)

2024-07-17 Thread via cfe-commits

https://github.com/cor3ntin updated 
https://github.com/llvm/llvm-project/pull/97210

>From c6ee783243e1888074778e2cb6de05df41cc8333 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 12:55:04 +0100
Subject: [PATCH] [Clang] Warn with -Wpre-c23-compat instead of
 -Wpre-c++17-compat for u8 character literals in C23

---
 clang/docs/ReleaseNotes.rst | 2 ++
 clang/include/clang/Basic/DiagnosticLexKinds.td | 3 +++
 clang/lib/Lex/Lexer.cpp | 4 +++-
 clang/test/Sema/pre-c2x-compat.c| 1 +
 4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c720e47dbe35b..d2939ef7a875c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -627,6 +627,8 @@ Improvements to Clang's diagnostics
   used rather than when they are needed for constant evaluation or when code 
is generated for them.
   The check is now stricter to prevent crashes for some unsupported 
declarations (Fixes #GH95495).
 
+- Clang now warns for u8 character literals used in C23 with 
``-Wpre-c23-compat`` instead of ``-Wpre-c++17-compat``.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 12d7b8c0205ee..fc14bb6aa2165 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -283,6 +283,9 @@ def warn_cxx98_compat_unicode_literal : Warning<
 def warn_cxx14_compat_u8_character_literal : Warning<
   "unicode literals are incompatible with C++ standards before C++17">,
   InGroup, DefaultIgnore;
+def warn_c17_compat_u8_character_literal : Warning<
+  "unicode literals are incompatible with C standards before C23">,
+  InGroup, DefaultIgnore;
 def warn_cxx11_compat_user_defined_literal : Warning<
   "identifier after literal will be treated as a user-defined literal suffix "
   "in C++11">, InGroup, DefaultIgnore;
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b3862..c61d81e93d990 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -2428,7 +2428,9 @@ bool Lexer::LexCharConstant(Token &Result, const char 
*CurPtr,
   ? diag::warn_cxx98_compat_unicode_literal
   : diag::warn_c99_compat_unicode_literal);
 else if (Kind == tok::utf8_char_constant)
-  Diag(BufferPtr, diag::warn_cxx14_compat_u8_character_literal);
+  Diag(BufferPtr, LangOpts.CPlusPlus
+  ? diag::warn_cxx14_compat_u8_character_literal
+  : diag::warn_c17_compat_u8_character_literal);
   }
 
   char C = getAndAdvanceChar(CurPtr, Result);
diff --git a/clang/test/Sema/pre-c2x-compat.c b/clang/test/Sema/pre-c2x-compat.c
index fad472f1f72d5..15bb9b58349fa 100644
--- a/clang/test/Sema/pre-c2x-compat.c
+++ b/clang/test/Sema/pre-c2x-compat.c
@@ -1,3 +1,4 @@
 // RUN: %clang_cc1 %s -std=c2x -Wpre-c2x-compat -pedantic -fsyntax-only -verify
 
 int digit_seps = 123'456; // expected-warning {{digit separators are 
incompatible with C standards before C23}}
+unsigned char u8_char = u8'x'; // expected-warning {{unicode literals are 
incompatible with C standards before C23}}

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


[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-17 Thread via cfe-commits

https://github.com/cor3ntin updated 
https://github.com/llvm/llvm-project/pull/97208

>From ef0072d1fc9b14f7ee657fa95f44a686b78b525a Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 12:07:54 +0100
Subject: [PATCH 1/9] [Clang] [C23] Implement N2653: u8 strings are char8_t[]

---
 clang/docs/ReleaseNotes.rst   |  6 
 .../clang/Basic/DiagnosticSemaKinds.td|  5 +++-
 clang/lib/Frontend/InitPreprocessor.cpp   |  6 ++--
 clang/lib/Headers/stdatomic.h |  5 
 clang/lib/Sema/SemaExpr.cpp   | 23 ++-
 clang/test/C/C2x/n2653.c  | 29 +++
 clang/www/c_status.html   |  2 +-
 7 files changed, 65 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/C/C2x/n2653.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c720e47dbe35b..e51be81d8b11a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,12 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Compiler support for `N2653 char8_t: A type for UTF-8 characters and strings`
+  `_: ``u8`` string
+  literals are now of type ``char8_t[N]`` in C23 and expose
+  ``__CLANG_ATOMIC_CHAR8_T_LOCK_FREE``/``__GCC_ATOMIC_CHAR8_T_LOCK_FREE`` to
+  implement the corresponding macro in .
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5dc36c594bcb7..6a00b92df1c36 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7252,7 +7252,10 @@ def err_array_init_utf8_string_into_char : Error<
 def warn_cxx20_compat_utf8_string : Warning<
   "type of UTF-8 string literal will change from array of const char to "
   "array of const char8_t in C++20">, InGroup, DefaultIgnore;
-def note_cxx20_compat_utf8_string_remove_u8 : Note<
+def warn_c23_compat_utf8_string : Warning<
+  "type of UTF-8 string literal will change from array of char to "
+  "array of char8_t in C23">, InGroup, DefaultIgnore;
+def note_cxx20_c23_compat_utf8_string_remove_u8 : Note<
   "remove 'u8' prefix to avoid a change of behavior; "
   "Clang encodes unprefixed narrow string literals as UTF-8">;
 def err_array_init_different_type : Error<
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index 55ec460064830..6270c37342bcf 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1342,8 +1342,10 @@ static void InitializePredefinedMacros(const TargetInfo 
&TI,
   getLockFreeValue(TI.get##Type##Width(), TI));
 DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
 DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-if (LangOpts.Char8)
-  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
+// char8_t has the same representation / width as unsigned
+// char in C++ and is a typedef for unsigned char in C23
+if (LangOpts.Char8 || LangOpts.C23)
+  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char);
 DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
 DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
 DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
diff --git a/clang/lib/Headers/stdatomic.h b/clang/lib/Headers/stdatomic.h
index 9c103d98af8c5..c33cd8083525c 100644
--- a/clang/lib/Headers/stdatomic.h
+++ b/clang/lib/Headers/stdatomic.h
@@ -35,6 +35,10 @@ extern "C" {
 
 #define ATOMIC_BOOL_LOCK_FREE   __CLANG_ATOMIC_BOOL_LOCK_FREE
 #define ATOMIC_CHAR_LOCK_FREE   __CLANG_ATOMIC_CHAR_LOCK_FREE
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||  
\
+defined(__cplusplus)
+#define ATOMIC_CHAR8_T_LOCK_FREE__CLANG_ATOMIC_CHAR8_T_LOCK_FREE
+#endif
 #define ATOMIC_CHAR16_T_LOCK_FREE   __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
 #define ATOMIC_CHAR32_T_LOCK_FREE   __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
 #define ATOMIC_WCHAR_T_LOCK_FREE__CLANG_ATOMIC_WCHAR_T_LOCK_FREE
@@ -104,6 +108,7 @@ typedef _Atomic(long)   atomic_long;
 typedef _Atomic(unsigned long)  atomic_ulong;
 typedef _Atomic(long long)  atomic_llong;
 typedef _Atomic(unsigned long long) atomic_ullong;
+typedef _Atomic(unsigned char)  atomic_char8_t;
 typedef _Atomic(uint_least16_t) atomic_char16_t;
 typedef _Atomic(uint_least32_t) atomic_char32_t;
 typedef _Atomic(wchar_t)atomic_wchar_t;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index db44cfe1288b6..a1b060f7f1510 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2082,6 +2082,8 @@ Sema::ActOnStringLiteral(ArrayRef StringToks, 
Scope *UDLScope) {
   } else if (Literal.isUTF8()) {
 if (

[clang] 329e7c8 - [Clang] [C23] Implement N2653: u8 strings are char8_t[] (#97208)

2024-07-17 Thread via cfe-commits

Author: Mital Ashok
Date: 2024-07-17T14:14:31+02:00
New Revision: 329e7c80ac2dbc16c267390da5f1baaf1cd438b1

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

LOG: [Clang] [C23] Implement N2653: u8 strings are char8_t[] (#97208)

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm

Closes #97202

-

Co-authored-by: cor3ntin 

Added: 
clang/test/C/C23/n2653.c

Modified: 
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Frontend/InitPreprocessor.cpp
clang/lib/Headers/stdatomic.h
clang/lib/Sema/SemaExpr.cpp
clang/www/c_status.html

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6dc45956a9afb..923f3d0a46164 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -362,6 +362,12 @@ C23 Feature Support
 - Added the ``FLT_NORM_MAX``, ``DBL_NORM_MAX``, and ``LDBL_NORM_MAX`` to the
   freestanding implementation of  that ships with Clang.
 
+- Compiler support for `N2653 char8_t: A type for UTF-8 characters and strings`
+  `_: ``u8`` string
+  literals are now of type ``char8_t[N]`` in C23 and expose
+  ``__CLANG_ATOMIC_CHAR8_T_LOCK_FREE``/``__GCC_ATOMIC_CHAR8_T_LOCK_FREE`` to
+  implement the corresponding macro in .
+
 Non-comprehensive list of changes in this release
 -
 

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 52ff4b026a60e..de3d94155a9a0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7249,7 +7249,10 @@ def err_array_init_utf8_string_into_char : Error<
 def warn_cxx20_compat_utf8_string : Warning<
   "type of UTF-8 string literal will change from array of const char to "
   "array of const char8_t in C++20">, InGroup, DefaultIgnore;
-def note_cxx20_compat_utf8_string_remove_u8 : Note<
+def warn_c23_compat_utf8_string : Warning<
+  "type of UTF-8 string literal will change from array of char to "
+  "array of char8_t in C23">, InGroup, DefaultIgnore;
+def note_cxx20_c23_compat_utf8_string_remove_u8 : Note<
   "remove 'u8' prefix to avoid a change of behavior; "
   "Clang encodes unprefixed narrow string literals as UTF-8">;
 def err_array_init_
diff erent_type : Error<

diff  --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index d40d78a38540b..920ddf7e59913 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1170,6 +1170,8 @@ static void InitializePredefinedMacros(const TargetInfo 
&TI,
   DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
   DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
   DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder);
+  if (LangOpts.C23)
+DefineType("__CHAR8_TYPE__", TI.UnsignedChar, Builder);
   DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder);
   DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);
 
@@ -1349,8 +1351,10 @@ static void InitializePredefinedMacros(const TargetInfo 
&TI,
   getLockFreeValue(TI.get##Type##Width(), TI));
 DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
 DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-if (LangOpts.Char8)
-  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
+// char8_t has the same representation / width as unsigned
+// char in C++ and is a typedef for unsigned char in C23
+if (LangOpts.Char8 || LangOpts.C23)
+  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char);
 DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
 DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
 DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);

diff  --git a/clang/lib/Headers/stdatomic.h b/clang/lib/Headers/stdatomic.h
index 9c103d98af8c5..2027055f38796 100644
--- a/clang/lib/Headers/stdatomic.h
+++ b/clang/lib/Headers/stdatomic.h
@@ -35,6 +35,9 @@ extern "C" {
 
 #define ATOMIC_BOOL_LOCK_FREE   __CLANG_ATOMIC_BOOL_LOCK_FREE
 #define ATOMIC_CHAR_LOCK_FREE   __CLANG_ATOMIC_CHAR_LOCK_FREE
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define ATOMIC_CHAR8_T_LOCK_FREE__CLANG_ATOMIC_CHAR8_T_LOCK_FREE
+#endif
 #define ATOMIC_CHAR16_T_LOCK_FREE   __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
 #define ATOMIC_CHAR32_T_LOCK_FREE   __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
 #define ATOMIC_WCHAR_T_LOCK_FREE__CLANG_ATOMIC_WCHAR_T_LOCK_FREE
@@ -104,6 +107,9 @@ typedef _Atomic(long)   atomic_long;
 typedef _Atomic(unsigned long)  atomic_ulong;
 typedef _Atomic(long long)  atomic_llong;
 typedef _Atomic(unsigned long long) atomic_ullong;
+#if defined(_

[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-17 Thread via cfe-commits

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-07-17 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Thanks for all the help with this issue. I think I figured it out - there was 
an unsigned wraparound some time before doing the actual allocation, which 
caused us to write over the bounds of the allocation. I've pushed 
https://github.com/llvm/llvm-project/commit/72b3d7bc87019ba7ef268ce322f90382f01b11af
 to ensure this doesn't happen and 
https://github.com/llvm/llvm-project/commit/e94e72a0c2293a02ea6c5335ac5fbc2d34de13f1
 to implement the dynamic allocation management.

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


[clang] [llvm] [openmp] [Clang][OpenMP] Add reverse directive (PR #92916)

2024-07-17 Thread Michael Kruse via cfe-commits


@@ -15749,6 +15757,186 @@ StmtResult 
SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses,
 buildPreInits(Context, PreInits));
 }
 
+StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
+   SourceLocation StartLoc,
+   SourceLocation EndLoc) {
+  ASTContext &Context = getASTContext();
+  Scope *CurScope = SemaRef.getCurScope();
+
+  // Empty statement should only be possible if there already was an error.
+  if (!AStmt)
+return StmtError();
+
+  constexpr unsigned NumLoops = 1;
+  Stmt *Body = nullptr;
+  SmallVector LoopHelpers(
+  NumLoops);
+  SmallVector, NumLoops + 1> OriginalInits;
+  if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers,
+  Body, OriginalInits))
+return StmtError();
+
+  // Delay applying the transformation to when template is completely
+  // instantiated.
+  if (SemaRef.CurContext->isDependentContext())
+return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
+   nullptr, nullptr);
+
+  assert(LoopHelpers.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  assert(OriginalInits.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
+
+  // Find the loop statement.
+  Stmt *LoopStmt = nullptr;
+  collectLoopStmts(AStmt, {LoopStmt});
+
+  // Determine the PreInit declarations.
+  SmallVector PreInits;
+  addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
+
+  auto *IterationVarRef = cast(LoopHelper.IterationVarRef);
+  QualType IVTy = IterationVarRef->getType();
+  uint64_t IVWidth = Context.getTypeSize(IVTy);
+  auto *OrigVar = cast(LoopHelper.Counters.front());
+
+  // Iteration variable SourceLocations.
+  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
+  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
+  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
+
+  // Locations pointing to the transformation.
+  SourceLocation TransformLoc = StartLoc;
+  SourceLocation TransformLocBegin = StartLoc;
+  SourceLocation TransformLocEnd = EndLoc;
+
+  // Internal variable names.
+  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
+  std::string TripCountName = (Twine(".tripcount.") + OrigVarName).str();
+  std::string ForwardIVName = (Twine(".forward.iv.") + OrigVarName).str();
+  std::string ReversedIVName = (Twine(".reversed.iv.") + OrigVarName).str();

Meinersbur wrote:

SmallString works, but requires a separate `append` statement. Applied.

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


[clang] [libcxx] [Clang] Implement CWG2137 (list-initialization from objects of the same type) (PR #94355)

2024-07-17 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman approved this pull request.

LGTM!

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


[clang] [llvm] [openmp] [Clang][OpenMP] Add reverse directive (PR #92916)

2024-07-17 Thread Alexey Bataev via cfe-commits

https://github.com/alexey-bataev approved this pull request.

LG with a nit

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


[clang] [llvm] [openmp] [Clang][OpenMP] Add reverse directive (PR #92916)

2024-07-17 Thread Alexey Bataev via cfe-commits

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


[clang] [llvm] [openmp] [Clang][OpenMP] Add reverse directive (PR #92916)

2024-07-17 Thread Alexey Bataev via cfe-commits


@@ -14658,6 +14666,193 @@ StmtResult 
SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses,
 buildPreInits(Context, PreInits));
 }
 
+StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
+   SourceLocation StartLoc,
+   SourceLocation EndLoc) {
+  ASTContext &Context = getASTContext();
+  Scope *CurScope = SemaRef.getCurScope();
+
+  // Empty statement should only be possible if there already was an error.
+  if (!AStmt)
+return StmtError();
+
+  constexpr unsigned NumLoops = 1;
+  Stmt *Body = nullptr;
+  SmallVector LoopHelpers(
+  NumLoops);
+  SmallVector, NumLoops + 1> OriginalInits;
+  if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers,
+  Body, OriginalInits))
+return StmtError();
+
+  // Delay applying the transformation to when template is completely
+  // instantiated.
+  if (SemaRef.CurContext->isDependentContext())
+return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
+   nullptr, nullptr);
+
+  assert(LoopHelpers.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  assert(OriginalInits.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
+
+  // Find the loop statement.
+  Stmt *LoopStmt = nullptr;
+  collectLoopStmts(AStmt, {LoopStmt});
+
+  // Determine the PreInit declarations.
+  SmallVector PreInits;
+  addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
+
+  auto *IterationVarRef = cast(LoopHelper.IterationVarRef);
+  QualType IVTy = IterationVarRef->getType();
+  uint64_t IVWidth = Context.getTypeSize(IVTy);
+  auto *OrigVar = cast(LoopHelper.Counters.front());
+
+  // Iteration variable SourceLocations.
+  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
+  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
+  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
+
+  // Locations pointing to the transformation.
+  SourceLocation TransformLoc = StartLoc;
+  SourceLocation TransformLocBegin = StartLoc;
+  SourceLocation TransformLocEnd = EndLoc;
+
+  // Internal variable names.
+  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
+  SmallString<64> ForwardIVName(".forward.iv.");
+  ForwardIVName += OrigVarName;
+  SmallString<64> ReversedIVName(".reversed.iv.");
+  ReversedIVName += OrigVarName;
+
+  // LoopHelper.Updates will read the logical iteration number from
+  // LoopHelper.IterationVarRef, compute the value of the user loop counter of
+  // that logical iteration from it, then assign it to the user loop counter
+  // variable. We cannot directly use LoopHelper.IterationVarRef as the
+  // induction variable of the generated loop because it may cause an 
underflow:
+  // \code{.c}
+  //   for (unsigned i = 0; i < n; ++i)
+  // body(i);
+  // \endcode
+  //
+  // Naive reversal:
+  // \code{.c}
+  //   for (unsigned i = n-1; i >= 0; --i)
+  // body(i);
+  // \endcode
+  //
+  // Instead, we introduce a new iteration variable representing the logical
+  // iteration counter of the original loop, convert it to the logical 
iteration
+  // number of the reversed loop, then let LoopHelper.Updates compute the 
user's
+  // loop iteration variable from it.
+  // \code{.cpp}
+  //   for (auto .forward.iv = 0; .forward.iv < n; ++.forward.iv) {
+  // auto .reversed.iv = n - .forward.iv - 1;
+  // i = (.reversed.iv + 0) * 1;// LoopHelper.Updates
+  // body(i);   // Body
+  //   }
+  // \endcode
+
+  // Subexpressions with more than one use. One of the constraints of an AST is
+  // that every node object must appear at most once, hence we define a lambda
+  // that creates a new AST node at every use.
+  CaptureVars CopyTransformer(SemaRef);
+  auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
+return AssertSuccess(
+CopyTransformer.TransformExpr(LoopHelper.NumIterations));
+  };
+
+  // Create the iteration variable for the forward loop (from 0 to n-1).
+  VarDecl *ForwardIVDecl =
+  buildVarDecl(SemaRef, {}, IVTy, ForwardIVName, nullptr, OrigVar);
+  auto MakeForwardRef = [&SemaRef = this->SemaRef, ForwardIVDecl, IVTy,
+ OrigVarLoc]() {
+return buildDeclRefExpr(SemaRef, ForwardIVDecl, IVTy, OrigVarLoc);
+  };
+
+  // Iteration variable for the reversed induction variable (from n-1 downto 
0):
+  // Reuse the iteration variable created by checkOpenMPLoop.
+  auto *ReversedIVDecl = cast(IterationVarRef->getDecl());
+  ReversedIVDecl->setDeclName(
+  &SemaRef.PP.getIdentifierTable().get(ReversedIVName));
+
+  // For init-statement:
+  // \code{.cpp}
+  //   auto .forward.iv = 0;
+  // \

[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)

2024-07-17 Thread Fanbo Meng via cfe-commits

https://github.com/fanbo-meng updated 
https://github.com/llvm/llvm-project/pull/91384

>From 84e5ca4d8987d071d20b9dcba673b0c856762487 Mon Sep 17 00:00:00 2001
From: Fanbo Meng 
Date: Tue, 7 May 2024 13:36:38 -0400
Subject: [PATCH 01/11] [SystemZ][z/OS] Implement z/OS XPLINK ABI

The XPLINK calling convention is specified in the Language
Environment Vendor Interface, chapter 22,
(https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm)
and in Redbook XPLink: OS/390 Extra Performance Linkage
(http://www.redbooks.ibm.com/abstracts/sg245991.html?Open)
---
 clang/lib/CodeGen/CodeGenModule.cpp   |   2 +
 clang/lib/CodeGen/TargetInfo.h|   4 +
 clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++
 clang/test/CodeGen/zos-abi.c  | 162 +++
 4 files changed, 561 insertions(+)
 create mode 100644 clang/test/CodeGen/zos-abi.c

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 60ef28a0effaa..ffdce2417c67c 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
   case llvm::Triple::systemz: {
 bool SoftFloat = CodeGenOpts.FloatABI == "soft";
 bool HasVector = !SoftFloat && Target.getABI() == "vector";
+if (Triple.getOS() == llvm::Triple::ZOS)
+  return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat);
 return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat);
   }
 
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index f242d9e36ed40..e15f9bdf39356 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -527,6 +527,10 @@ std::unique_ptr
 createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector,
bool SoftFloatABI);
 
+std::unique_ptr
+createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector,
+bool SoftFloatABI);
+
 std::unique_ptr
 createTCETargetCodeGenInfo(CodeGenModule &CGM);
 
diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp 
b/clang/lib/CodeGen/Targets/SystemZ.cpp
index deaafc85a3157..d420286c71c16 100644
--- a/clang/lib/CodeGen/Targets/SystemZ.cpp
+++ b/clang/lib/CodeGen/Targets/SystemZ.cpp
@@ -10,6 +10,7 @@
 #include "TargetInfo.h"
 #include "clang/Basic/Builtins.h"
 #include "llvm/IR/IntrinsicsS390.h"
+#include 
 
 using namespace clang;
 using namespace clang::CodeGen;
@@ -529,9 +530,401 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const 
Type *Ty,
   return false;
 }
 
+//===--===//
+// z/OS XPLINK ABI Implementation
+//===--===//
+
+namespace {
+
+class ZOSXPLinkABIInfo : public ABIInfo {
+  const unsigned GPRBits = 64;
+  bool HasVector;
+
+public:
+  ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) : ABIInfo(CGT), HasVector(HV) {}
+
+  bool isPromotableIntegerType(QualType Ty) const;
+  bool isCompoundType(QualType Ty) const;
+  bool isVectorArgumentType(QualType Ty) const;
+  bool isFPArgumentType(QualType Ty) const;
+  QualType getSingleElementType(QualType Ty) const;
+  unsigned getMaxAlignFromTypeDefs(QualType Ty) const;
+  std::optional getFPTypeOfComplexLikeType(QualType Ty) const;
+
+  ABIArgInfo classifyReturnType(QualType RetTy,
+unsigned functionCallConv) const;
+  ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg,
+  unsigned functionCallConv) const;
+
+  void computeInfo(CGFunctionInfo &FI) const override {
+if (!getCXXABI().classifyReturnType(FI))
+  FI.getReturnInfo() =
+  classifyReturnType(FI.getReturnType(), FI.getCallingConvention());
+
+unsigned NumRequiredArgs = FI.getNumRequiredArgs();
+unsigned ArgNo = 0;
+
+for (auto &I : FI.arguments()) {
+  bool IsNamedArg = ArgNo < NumRequiredArgs;
+  I.info =
+  classifyArgumentType(I.type, IsNamedArg, FI.getCallingConvention());
+  ++ArgNo;
+}
+  }
+
+  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+QualType Ty) const override;
+};
+
+class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector)
+  : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) {
+SwiftInfo =
+std::make_unique(CGT, /*SwiftErrorInRegister=*/false);
+  }
+};
+
+} // namespace
+
+// Return true if the ABI requires Ty to be passed sign- or zero-
+// extended to 64 bits.
+bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const {
+  // Treat an enum type as its underlying type.
+  if (const EnumType *EnumTy = Ty->getAs())
+Ty = EnumTy->getDecl()->getIntegerType();
+
+  // Promotable integer types are required to be promoted by the ABI.
+  if (getContext().isPromotableIntegerType(

[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)

2024-07-17 Thread Fanbo Meng via cfe-commits


@@ -529,9 +530,355 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const 
Type *Ty,
   return false;
 }
 
+//===--===//
+// z/OS XPLINK ABI Implementation
+//===--===//
+
+namespace {
+
+class ZOSXPLinkABIInfo : public ABIInfo {
+  const unsigned GPRBits = 64;
+  bool HasVector;
+
+public:
+  ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) : ABIInfo(CGT), HasVector(HV) {}
+
+  bool isPromotableIntegerType(QualType Ty) const;
+  bool isVectorArgumentType(QualType Ty) const;
+  bool isFPArgumentType(QualType Ty) const;
+  QualType getSingleElementType(QualType Ty) const;
+  std::optional getFPTypeOfComplexLikeType(QualType Ty) const;
+
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const;
+
+  void computeInfo(CGFunctionInfo &FI) const override {
+if (!getCXXABI().classifyReturnType(FI))
+  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+
+unsigned NumRequiredArgs = FI.getNumRequiredArgs();
+unsigned ArgNo = 0;
+
+for (auto &I : FI.arguments()) {
+  bool IsNamedArg = ArgNo < NumRequiredArgs;
+  I.info = classifyArgumentType(I.type, IsNamedArg);
+  ++ArgNo;
+}
+  }
+
+  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+QualType Ty) const override;
+};
+
+class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector)
+  : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) {
+SwiftInfo =
+std::make_unique(CGT, /*SwiftErrorInRegister=*/false);
+  }
+};
+
+} // namespace
+
+// Return true if the ABI requires Ty to be passed sign- or zero-
+// extended to 64 bits.
+bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const {
+  // Treat an enum type as its underlying type.
+  if (const EnumType *EnumTy = Ty->getAs())
+Ty = EnumTy->getDecl()->getIntegerType();
+
+  // Promotable integer types are required to be promoted by the ABI.
+  if (getContext().isPromotableIntegerType(Ty))
+return true;
+
+  if (const auto *EIT = Ty->getAs())
+if (EIT->getNumBits() < 64)
+  return true;
+
+  // In addition to the usual promotable integer types, we also need to
+  // extend all 32-bit types, since the ABI requires promotion to 64 bits.
+  if (const BuiltinType *BT = Ty->getAs())
+switch (BT->getKind()) {
+case BuiltinType::Int:
+case BuiltinType::UInt:
+  return true;
+default:
+  break;
+}
+
+  return false;
+}
+
+bool ZOSXPLinkABIInfo::isVectorArgumentType(QualType Ty) const {
+  return (HasVector && Ty->isVectorType() &&
+  getContext().getTypeSize(Ty) <= 128);
+}
+
+bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const {
+  if (const BuiltinType *BT = Ty->getAs())
+switch (BT->getKind()) {
+case BuiltinType::Float:
+case BuiltinType::Double:
+case BuiltinType::LongDouble:
+  return true;
+default:
+  return false;
+}
+
+  return false;
+}
+
+QualType ZOSXPLinkABIInfo::getSingleElementType(QualType Ty) const {
+  const RecordType *RT = Ty->getAs();
+
+  if (RT && RT->isStructureOrClassType()) {
+const RecordDecl *RD = RT->getDecl();
+QualType Found;
+
+// If this is a C++ record, check the bases first.
+if (const CXXRecordDecl *CXXRD = dyn_cast(RD))
+  if (CXXRD->hasDefinition())
+for (const auto &I : CXXRD->bases()) {
+  QualType Base = I.getType();
+
+  // Empty bases don't affect things either way.
+  if (isEmptyRecord(getContext(), Base, true))
+continue;
+
+  if (!Found.isNull())
+return Ty;
+  Found = getSingleElementType(Base);
+}
+
+// Check the fields.
+for (const auto *FD : RD->fields()) {
+  QualType FT = FD->getType();
+
+  // Ignore empty fields.
+  if (isEmptyField(getContext(), FD, true))
+continue;
+
+  if (!Found.isNull())
+return Ty;
+
+  // Treat single element arrays as the element.
+  while (const ConstantArrayType *AT =
+ getContext().getAsConstantArrayType(FT)) {
+if (AT->getZExtSize() != 1)
+  break;
+FT = AT->getElementType();
+  }
+
+  Found = getSingleElementType(FT);
+}
+
+// Unlike isSingleElementStruct(), trailing padding is allowed.
+if (!Found.isNull())
+  return Found;
+  }
+
+  return Ty;
+}
+
+std::optional
+ZOSXPLinkABIInfo::getFPTypeOfComplexLikeType(QualType Ty) const {
+  if (const RecordType *RT = Ty->getAsStructureType()) {
+const RecordDecl *RD = RT->getDecl();
+
+// Check for non-empty base classes.
+if (const CXXRecordDecl *CXXRD = dyn_cast(RD))
+  if (CXXRD->hasDefinition())
+for (const auto &I : CXXRD->bases()) {
+  QualType Base = I.getType();
+   

  1   2   3   4   5   >