[clang] [Clang] Clarify diagnostic notes for implicitly generated deduction guides (PR #96084)

2024-06-24 Thread Haojian Wu via cfe-commits


@@ -12114,6 +12115,35 @@ static void NoteFunctionCandidate(Sema , 
OverloadCandidate *Cand,
 return;
   }
 
+  // If this is an implicit deduction guide against an implicitly defined
+  // constructor, add a note for it. Neither these deduction guides nor their
+  // corresponding constructors are explicitly spelled in the source code,

hokein wrote:

I have a different perspective: I'd prefer printing them as long as they are 
synthesized (not part of the written source code).

While the example of combined template parameters might not be the best one 
(and I agree that understanding them from existing contexts is often 
sufficient), the conjunction of associated constraints for a class and the 
corresponding constructor is probably less obvious. I think printing them would 
make the situation clearer and help users avoid guessing. Moreover, this 
approach would be consistent with what GCC does.

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


[clang] [Clang] Clarify diagnostic notes for implicitly generated deduction guides (PR #96084)

2024-06-21 Thread Haojian Wu via cfe-commits


@@ -12114,6 +12115,35 @@ static void NoteFunctionCandidate(Sema , 
OverloadCandidate *Cand,
 return;
   }
 
+  // If this is an implicit deduction guide against an implicitly defined
+  // constructor, add a note for it. Neither these deduction guides nor their
+  // corresponding constructors are explicitly spelled in the source code,

hokein wrote:

Any reason to filter out the "explicit constructor" case? We still synthesize a 
deduction guide from a constructor, and they are not identical, e.g. its 
template parameters is a combination of template parameters of the class and 
template parameters of the corresponding constructor. I think it is useful to 
print them as well.

I think a simple model here would be that we always print synthesized deduction 
guides (this covers the using-alias case.)

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


[clang] [Clang] Clarify diagnostic notes for implicitly generated deduction guides (PR #96084)

2024-06-21 Thread Haojian Wu via cfe-commits


@@ -12114,6 +12115,35 @@ static void NoteFunctionCandidate(Sema , 
OverloadCandidate *Cand,
 return;
   }
 
+  // If this is an implicit deduction guide against an implicitly defined
+  // constructor, add a note for it. Neither these deduction guides nor their
+  // corresponding constructors are explicitly spelled in the source code,
+  // and simply producing a deduction failure note around the heading of the
+  // enclosing RecordDecl would be confusing.
+  //
+  // We prefer adding such notes at the end of the last deduction failure
+  // reason because duplicate code snippets appearing in the diagnostic
+  // would likely become noisy.
+  auto _ = llvm::make_scope_exit([&] {
+auto *DG = dyn_cast(Fn);
+if (!DG || !DG->isImplicit() || DG->getCorrespondingConstructor())

hokein wrote:

(I assume we always print using-alias deduction guides)

Note that checking the implicit guides is not sufficient for using-alias 
deduction guides. Those synthesized from the explicitly written deduction guide 
will retain the explicit bit (to ensure correct function overload resolution).


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


[clang] [Clang] Clarify diagnostic notes for implicitly generated deduction guides (PR #96084)

2024-06-21 Thread Haojian Wu via cfe-commits

hokein wrote:


Thanks for the patch! +1 on the idea of printing deduction guides in 
diagnostics. This improves the experience for both users and compiler 
developers. This is https://github.com/llvm/llvm-project/issues/92393 :)

> Perhaps an approach more similar to what we display for ambiguous cast paths 
> would be better, i.e., listing each implicit deduction guide we tried in a 
> single note.
>
> Thanks for suggesting a better approach. However, implementing this would 
> require significant changes to our diagnostic logic for overloads. We 
> currently explain the reasons for deduction failure in subsequent notes, with 
> around 16 different kinds of deduction failures, each with its own diagnostic 
> message. Given this complexity, I don't think it's necessary (or feasible) to 
> special-case CTAD guides for each note.

In my opinion, including the deduction guide in the existing note (e.g., 
`candidate template "template S()-> S" ignored: ...`) is clearer 
and more concise. It seems that the current implementation in clang assumes all 
template candidates are written in the source code, which isn't true for the 
CTAD case. We could extend it to work for not-explicitly-written-in-source-code 
case. 
Although we have 19 `candidate template ignored` notes, they are mostly 
localized in `SemaOverload.cpp`. Extending them is possible but would require 
some work.

However, I don't feel strongly about this, and am also fine with the current 
implementation, as it has already improved the experience.





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


[clang] [Sema][CTAD] Allow user defined conversion for copy-list-initialization (PR #94752)

2024-06-18 Thread Haojian Wu via cfe-commits


@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s

hokein wrote:

yeah, that's expected, we disable the clang-format for all lit test files (see 
the `clang/test/.clang-format`).

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


[clang] [Sema][CTAD] Allow user defined conversion for copy-list-initialization (PR #94752)

2024-06-18 Thread Haojian Wu via cfe-commits

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


[clang] [Sema][CTAD] Allow user defined conversion for copy-list-initialization (PR #94752)

2024-06-18 Thread Haojian Wu via cfe-commits

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

thanks, looks good.

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


[clang] [Sema][CTAD] Allow user defined conversion for copy-list-initialization (PR #94752)

2024-06-18 Thread Haojian Wu via cfe-commits


@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s
+
+namespace std {
+  typedef decltype(sizeof(int)) size_t;
+
+  template 
+  struct initializer_list
+  {
+const E *p;
+size_t n;
+initializer_list(const E *p, size_t n) : p(p), n(n) {}
+  };
+
+  struct string {
+string(const char *);
+  };
+
+  // Classes to use to reproduce the exact scenario present in 62925.
+template
+class pair{
+public:
+pair(T f, Y s) {}
+};
+
+template
+class map {
+public:
+map(std::initializer_list>, int a = 4, int b = 5) {}
+};
+
+} // namespace std
+
+
+// Classes to test different levels of nestings and conversions.
+template
+class Contained {
+  public:
+  Contained(T, Y) {}
+};
+
+template
+class A {
+  public:
+  A(std::initializer_list >, int) {}
+};
+
+
+// This is the almost the exact code that was in issue #62925.
+void testOneLevelNesting() {
+  std::map mOk = {std::pair{5, 'a'}, {6, 'b'}, {7, 'c'}};
+
+  // Verify that narrowing conversion is disabled in the first level of 
nesting.
+  std::map mNarrow = {std::pair{5, 'a'}, {6.0f, 'b'}, {7, 'c'}}; // 
expected-error {{type 'float' cannot be narrowed to 'int' in initializer list}} 
// expected-note {{insert an explicit cast to silence this issue}}
+}
+
+void testMultipleLevelNesting() {
+  A aOk = {{Contained{5, 'c'}, {5, 'c'}}, 5};
+
+  // Verify that narrowing conversion is disabled when it is not in a nested
+  // in another std::initializer_list, but it happens in the most outer one.
+  A aNarrowNested = {{Contained{5, 'c'}, {5.0f, 'c'}}, 5}; // expected-error 
{{type 'float' cannot be narrowed to 'int' in initializer list}} // 
expected-note {{insert an explicit cast to silence this issue}}

hokein wrote:

Class `Contained` and `pair` look the same (also for `A` and `map`).

Can we reuse the `pair` and `map` to test the "mutiple level nesting" case?  
e.g. `std::map mNaarowNested = {{Contained{5, 'c'}, {5.0f, 'c'}}, 5}};` (you 
probably need to add a constructor `map(std::initializer_list>, 
int)`).

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


[clang] [Sema][CTAD] Allow user defined conversion for copy-list-initialization (PR #94752)

2024-06-18 Thread Haojian Wu via cfe-commits


@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s

hokein wrote:

nit: please format the test file.

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


[clang] [Sema][CTAD] Allow user defined conversion for copy-list-initialization (PR #94752)

2024-06-18 Thread Haojian Wu via cfe-commits

https://github.com/hokein commented:

The change looks good to me. Please add a note in 
`llvm-project/clang/docs/ReleaseNotes.rst`.

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


[clang] [Sema][CTAD] Allow user defined conversion for copy-list-initialization (PR #94752)

2024-06-18 Thread Haojian Wu via cfe-commits


@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s
+
+namespace std {
+  typedef decltype(sizeof(int)) size_t;
+
+  template 
+  struct initializer_list
+  {
+const E *p;
+size_t n;
+initializer_list(const E *p, size_t n) : p(p), n(n) {}
+  };
+
+  struct string {

hokein wrote:

nit: this is not used.

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


[clang] [Sema][CTAD] Allow user defined conversion for copy-list-initialization (PR #94752)

2024-06-18 Thread Haojian Wu via cfe-commits

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


[clang] [clang-tools-extra] [include-cleaner] Pass WorkingDir to suggestPathToFileForDiagnostics (PR #95114)

2024-06-14 Thread Haojian Wu via cfe-commits

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


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


[clang] [clang][HeaderSearch] Fix handling of relative file-paths in suggestPathToFileForDiagnostics (PR #95121)

2024-06-14 Thread Haojian Wu via cfe-commits

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


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


[clang] [Clang] Fix handling of brace ellison when building deduction guides (PR #94889)

2024-06-13 Thread Haojian Wu via cfe-commits


@@ -10918,22 +10944,24 @@ QualType 
Sema::DeduceTemplateSpecializationFromInitializer(
   if (!(RD->getDefinition() && RD->isAggregate()))
 return;
   QualType Ty = Context.getRecordType(RD);
-  SmallVector ElementTypes;
-
-  InitListChecker CheckInitList(*this, Entity, ListInit, Ty, ElementTypes);
-  if (!CheckInitList.HadError()) {
+  auto BuildAggregateDeductionGuide = [&](MutableArrayRef
+  ElementTypes,
+  bool BracedVersion = false) {
+if (ElementTypes.empty())
+  return;
 // C++ [over.match.class.deduct]p1.8:
 //   if e_i is of array type and x_i is a braced-init-list, T_i is an
 //   rvalue reference to the declared type of e_i and
 // C++ [over.match.class.deduct]p1.9:
-//   if e_i is of array type and x_i is a bstring-literal, T_i is an
+//   if e_i is of array type and x_i is a string-literal, T_i is an
 //   lvalue reference to the const-qualified declared type of e_i and
 // C++ [over.match.class.deduct]p1.10:
 //   otherwise, T_i is the declared type of e_i
-for (int I = 0, E = ListInit->getNumInits();
+for (int I = 0, E = BracedVersion ? ElementTypes.size()
+  : ListInit->getNumInits();
  I < E && !isa(ElementTypes[I]); ++I)
   if (ElementTypes[I]->isArrayType()) {
-if (isa(ListInit->getInit(I)))
+if (isa(ListInit->getInit(I)))

hokein wrote:

It seems the code is diveraging from the standard. 

over.match.class.deduct#1.8 says
> if e_i is of array type and x_i is a braced-init-list, T_i is an rvalue 
> reference to the declared type of e_i.

And with this change, we will run into this code path if x_i is a 
`desianged-intializer-list`.


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


[clang] [clang] Don't print extra space when dumping template names (PR #95213)

2024-06-13 Thread Haojian Wu via cfe-commits

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


[clang] [clang] Don't print extra space when dumping template names (PR #95213)

2024-06-13 Thread Haojian Wu via cfe-commits

hokein wrote:

Thanks for the review, I'd go with the current fix. 

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


[clang] [Clang] Fix handling of brace ellison when building deduction guides (PR #94889)

2024-06-12 Thread Haojian Wu via cfe-commits


@@ -1449,7 +1449,10 @@ void InitListChecker::CheckSubElementType(const 
InitializedEntity ,
   //   dependent non-array type or an array type with a value-dependent
   //   bound
   assert(AggrDeductionCandidateParamTypes);
-  if (!isa_and_nonnull(
+  // Don't consider the brace elision if the initializer is a
+  // braced-init-list.
+  if (isa(expr) ||

hokein wrote:

I think this code does the right thing, to make sure my understanding of the 
code is correct.

Given the example

```
template  struct Foo {
  T t[2];
};

Foo t = {{1, 2}};
```
The `x1` is a brace-init-list `{1, 2}`, the corresponding `e1` is `T t[2]`, as 
the `e1` has a dependent type we can't perform semantic checks to see whether 
the `T t[2]` can be initialized by `x1`, we always assume true here. (This has 
an effect that we will generate the deduction guide even for invalid case e.g. 
`x1` is `{1, 2, 3}`, but this is fine as this code will be reject during 
template instantiation afterwards.)

If my understanding is right, can you rephrase the comment `Don't consider the 
brace elision if the initializer is a braced-init-list.`? Readers can be easily 
confused with the comment above on L1447 (both are saying brace elision, but 
they are different). 




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


[clang] [Clang] Fix handling of brace ellison when building deduction guides (PR #94889)

2024-06-12 Thread Haojian Wu via cfe-commits


@@ -10918,22 +10944,24 @@ QualType 
Sema::DeduceTemplateSpecializationFromInitializer(
   if (!(RD->getDefinition() && RD->isAggregate()))
 return;
   QualType Ty = Context.getRecordType(RD);
-  SmallVector ElementTypes;
-
-  InitListChecker CheckInitList(*this, Entity, ListInit, Ty, ElementTypes);
-  if (!CheckInitList.HadError()) {
+  auto BuildAggregateDeductionGuide = [&](MutableArrayRef
+  ElementTypes,
+  bool BracedVersion = false) {
+if (ElementTypes.empty())
+  return;
 // C++ [over.match.class.deduct]p1.8:
 //   if e_i is of array type and x_i is a braced-init-list, T_i is an
 //   rvalue reference to the declared type of e_i and
 // C++ [over.match.class.deduct]p1.9:
-//   if e_i is of array type and x_i is a bstring-literal, T_i is an
+//   if e_i is of array type and x_i is a string-literal, T_i is an
 //   lvalue reference to the const-qualified declared type of e_i and
 // C++ [over.match.class.deduct]p1.10:
 //   otherwise, T_i is the declared type of e_i
-for (int I = 0, E = ListInit->getNumInits();
+for (int I = 0, E = BracedVersion ? ElementTypes.size()
+  : ListInit->getNumInits();
  I < E && !isa(ElementTypes[I]); ++I)
   if (ElementTypes[I]->isArrayType()) {
-if (isa(ListInit->getInit(I)))
+if (isa(ListInit->getInit(I)))

hokein wrote:

Hmm, from the grammar rules, I can see designated-initalizer-list can be one of 
the element of a braced-init-list (e.g. `{ designated-initializer-list }`, but 
I can't infer `a designated-initializer-list is a braced-init-list`.

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


[clang] [clang] Don't print extra space when dumping template names (PR #95213)

2024-06-12 Thread Haojian Wu via cfe-commits

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

>From 3c96bf1b16360f52b235d31c08644a2749e7c808 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 12 Jun 2024 11:24:10 +0200
Subject: [PATCH] [clang] Don't print extra blank when dump the template name.

---
 clang/lib/AST/TextNodeDumper.cpp| 2 +-
 clang/test/AST/ast-dump-ctad-alias.cpp  | 4 ++--
 clang/test/AST/ast-dump-template-decls.cpp  | 6 +++---
 clang/test/AST/ast-dump-using-template.cpp  | 8 
 clang/test/SemaTemplate/deduction-guide.cpp | 4 ++--
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index e1a2709507eff..a26f50f0719c1 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1140,7 +1140,7 @@ void TextNodeDumper::dumpTemplateName(TemplateName TN, 
StringRef Label) {
 llvm::raw_svector_ostream SS(Str);
 TN.print(SS, PrintPolicy);
   }
-  OS << " '" << Str << "'";
+  OS << "'" << Str << "'";
 
   if (Context) {
 if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN);
diff --git a/clang/test/AST/ast-dump-ctad-alias.cpp 
b/clang/test/AST/ast-dump-ctad-alias.cpp
index cd3b8c6821344..a4b6f06547443 100644
--- a/clang/test/AST/ast-dump-ctad-alias.cpp
+++ b/clang/test/AST/ast-dump-ctad-alias.cpp
@@ -36,11 +36,11 @@ Out2::AInner t(1.0);
 // CHECK-NEXT: | | |   `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' 
dependent depth 1 index 0
 // CHECK-NEXT: | | `-TypeTraitExpr {{.*}} 'bool' __is_deducible
 // CHECK-NEXT: | |   |-DeducedTemplateSpecializationType {{.*}} 
'Out2::AInner' dependent
-// CHECK-NEXT: | |   | `-name:  'Out2::AInner'
+// CHECK-NEXT: | |   | `-name: 'Out2::AInner'
 // CHECK-NEXT: | |   |   `-TypeAliasTemplateDecl {{.+}} AInner{{$}}
 // CHECK-NEXT: | |   `-ElaboratedType {{.*}} 'Inner' 
sugar dependent
 // CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 
'Inner' dependent
-// CHECK-NEXT: | |   |-name:  'Inner':'Out::Inner' qualified
+// CHECK-NEXT: | |   |-name: 'Inner':'Out::Inner' qualified
 // CHECK-NEXT: | |   | `-ClassTemplateDecl {{.+}} Inner{{$}}
 // CHECK-NEXT: | |   `-TemplateArgument type 'type-parameter-1-0'
 // CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 
'type-parameter-1-0'
diff --git a/clang/test/AST/ast-dump-template-decls.cpp 
b/clang/test/AST/ast-dump-template-decls.cpp
index fea14abb3b2f4..f0a6204ce3cfa 100644
--- a/clang/test/AST/ast-dump-template-decls.cpp
+++ b/clang/test/AST/ast-dump-template-decls.cpp
@@ -117,7 +117,7 @@ using type2 = typename C::type1;
 // CHECK:  TypeAliasDecl 0x{{[^ ]*}}  col:7 
type2 'typename C::type1':'void (int)'
 // CHECK-NEXT: ElaboratedType 0x{{[^ ]*}} 'typename C::type1' sugar
 // CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1' sugar alias
-// CHECK-NEXT: name:  'C::type1':'PR55886::C::type1' qualified
+// CHECK-NEXT: name: 'C::type1':'PR55886::C::type1' qualified
 // CHECK-NEXT: NestedNameSpecifier TypeSpec 'C':'PR55886::C'
 // CHECK-NEXT: TypeAliasTemplateDecl {{.+}} type1
 // CHECK-NEXT: TemplateArgument type 'void'
@@ -153,7 +153,7 @@ template  struct D {
 };
 using t2 = D::B;
 // CHECK:  TemplateSpecializationType 0x{{[^ ]*}} 'B' sugar 
alias{{$}}
-// CHECK-NEXT: name:  'D::B':'PR56099::D::B' 
qualified
+// CHECK-NEXT: name: 'D::B':'PR56099::D::B' qualified
 // CHECK:  FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int 
(*)(char, short))' cdecl
 // CHECK:  FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl
 // CHECK:  SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename 
depth 0 index 0 ... T pack_index 1
@@ -175,7 +175,7 @@ template class E {};
 using test1 = D;
 // CHECK:  TypeAliasDecl 0x{{[^ ]*}}  col:7 
test1 'D':'subst_default_argument::E>'
 // CHECK:  TemplateSpecializationType 0x{{[^ ]*}} 'A' sugar
-// CHECK-NEXT: |-name:  'A':'subst_default_argument::A' qualified
+// CHECK-NEXT: |-name: 'A':'subst_default_argument::A' qualified
 // CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A
 // CHECK-NEXT: |-TemplateArgument type 'int'
 // CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class 
depth 0 index 1 D2
diff --git a/clang/test/AST/ast-dump-using-template.cpp 
b/clang/test/AST/ast-dump-using-template.cpp
index 22b9b76612add..75db5eb5a9d1c 100644
--- a/clang/test/AST/ast-dump-using-template.cpp
+++ b/clang/test/AST/ast-dump-using-template.cpp
@@ -21,7 +21,7 @@ using A = S;
 // CHECK:  TypeAliasDecl
 // CHECK-NEXT: `-ElaboratedType {{.*}} 'S' sugar dependent
 // CHECK-NEXT:   `-TemplateSpecializationType {{.*}} 'S' dependent
-// CHECK-NEXT: |-name:  'S':'ns::S' qualified
+// CHECK-NEXT: |-name: 'S':'ns::S' qualified
 // CHECk-NEXT: | |-UsingShadowDecl {{.+}} ClassTemplate {{.+}} 'S'
 
 // TemplateName in TemplateArgument.
@@ -30,7 +30,7 @@ using B = X;
 // CHECK:  

[clang] [clang] fix broken canonicalization of DeducedTemplateSpecializationType (PR #95202)

2024-06-12 Thread Haojian Wu via cfe-commits

https://github.com/hokein commented:

good catch, the fix looks good to me overall, I will leave the final stamp to 
@ChuanqiXu9.

(I agree that it would be nice to have a regression test if it is not too hard 
to reduce from libcxx)

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


[clang] [clang] Don't print extra space when dumping template names (PR #95213)

2024-06-12 Thread Haojian Wu via cfe-commits

https://github.com/hokein created 
https://github.com/llvm/llvm-project/pull/95213

None

>From c5f5d784a8cab287d3ec826a2636874ad9498563 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 12 Jun 2024 11:24:10 +0200
Subject: [PATCH] [clang] Don't print extra blank when dump the template name.

---
 clang/lib/AST/TextNodeDumper.cpp   | 2 +-
 clang/test/AST/ast-dump-ctad-alias.cpp | 4 ++--
 clang/test/AST/ast-dump-template-decls.cpp | 6 +++---
 clang/test/AST/ast-dump-using-template.cpp | 8 
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index e1a2709507eff..a26f50f0719c1 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1140,7 +1140,7 @@ void TextNodeDumper::dumpTemplateName(TemplateName TN, 
StringRef Label) {
 llvm::raw_svector_ostream SS(Str);
 TN.print(SS, PrintPolicy);
   }
-  OS << " '" << Str << "'";
+  OS << "'" << Str << "'";
 
   if (Context) {
 if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN);
diff --git a/clang/test/AST/ast-dump-ctad-alias.cpp 
b/clang/test/AST/ast-dump-ctad-alias.cpp
index cd3b8c6821344..a4b6f06547443 100644
--- a/clang/test/AST/ast-dump-ctad-alias.cpp
+++ b/clang/test/AST/ast-dump-ctad-alias.cpp
@@ -36,11 +36,11 @@ Out2::AInner t(1.0);
 // CHECK-NEXT: | | |   `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' 
dependent depth 1 index 0
 // CHECK-NEXT: | | `-TypeTraitExpr {{.*}} 'bool' __is_deducible
 // CHECK-NEXT: | |   |-DeducedTemplateSpecializationType {{.*}} 
'Out2::AInner' dependent
-// CHECK-NEXT: | |   | `-name:  'Out2::AInner'
+// CHECK-NEXT: | |   | `-name: 'Out2::AInner'
 // CHECK-NEXT: | |   |   `-TypeAliasTemplateDecl {{.+}} AInner{{$}}
 // CHECK-NEXT: | |   `-ElaboratedType {{.*}} 'Inner' 
sugar dependent
 // CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 
'Inner' dependent
-// CHECK-NEXT: | |   |-name:  'Inner':'Out::Inner' qualified
+// CHECK-NEXT: | |   |-name: 'Inner':'Out::Inner' qualified
 // CHECK-NEXT: | |   | `-ClassTemplateDecl {{.+}} Inner{{$}}
 // CHECK-NEXT: | |   `-TemplateArgument type 'type-parameter-1-0'
 // CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 
'type-parameter-1-0'
diff --git a/clang/test/AST/ast-dump-template-decls.cpp 
b/clang/test/AST/ast-dump-template-decls.cpp
index fea14abb3b2f4..f0a6204ce3cfa 100644
--- a/clang/test/AST/ast-dump-template-decls.cpp
+++ b/clang/test/AST/ast-dump-template-decls.cpp
@@ -117,7 +117,7 @@ using type2 = typename C::type1;
 // CHECK:  TypeAliasDecl 0x{{[^ ]*}}  col:7 
type2 'typename C::type1':'void (int)'
 // CHECK-NEXT: ElaboratedType 0x{{[^ ]*}} 'typename C::type1' sugar
 // CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1' sugar alias
-// CHECK-NEXT: name:  'C::type1':'PR55886::C::type1' qualified
+// CHECK-NEXT: name: 'C::type1':'PR55886::C::type1' qualified
 // CHECK-NEXT: NestedNameSpecifier TypeSpec 'C':'PR55886::C'
 // CHECK-NEXT: TypeAliasTemplateDecl {{.+}} type1
 // CHECK-NEXT: TemplateArgument type 'void'
@@ -153,7 +153,7 @@ template  struct D {
 };
 using t2 = D::B;
 // CHECK:  TemplateSpecializationType 0x{{[^ ]*}} 'B' sugar 
alias{{$}}
-// CHECK-NEXT: name:  'D::B':'PR56099::D::B' 
qualified
+// CHECK-NEXT: name: 'D::B':'PR56099::D::B' qualified
 // CHECK:  FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int 
(*)(char, short))' cdecl
 // CHECK:  FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl
 // CHECK:  SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename 
depth 0 index 0 ... T pack_index 1
@@ -175,7 +175,7 @@ template class E {};
 using test1 = D;
 // CHECK:  TypeAliasDecl 0x{{[^ ]*}}  col:7 
test1 'D':'subst_default_argument::E>'
 // CHECK:  TemplateSpecializationType 0x{{[^ ]*}} 'A' sugar
-// CHECK-NEXT: |-name:  'A':'subst_default_argument::A' qualified
+// CHECK-NEXT: |-name: 'A':'subst_default_argument::A' qualified
 // CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A
 // CHECK-NEXT: |-TemplateArgument type 'int'
 // CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class 
depth 0 index 1 D2
diff --git a/clang/test/AST/ast-dump-using-template.cpp 
b/clang/test/AST/ast-dump-using-template.cpp
index 22b9b76612add..75db5eb5a9d1c 100644
--- a/clang/test/AST/ast-dump-using-template.cpp
+++ b/clang/test/AST/ast-dump-using-template.cpp
@@ -21,7 +21,7 @@ using A = S;
 // CHECK:  TypeAliasDecl
 // CHECK-NEXT: `-ElaboratedType {{.*}} 'S' sugar dependent
 // CHECK-NEXT:   `-TemplateSpecializationType {{.*}} 'S' dependent
-// CHECK-NEXT: |-name:  'S':'ns::S' qualified
+// CHECK-NEXT: |-name: 'S':'ns::S' qualified
 // CHECk-NEXT: | |-UsingShadowDecl {{.+}} ClassTemplate {{.+}} 'S'
 
 // TemplateName in TemplateArgument.
@@ -30,7 +30,7 @@ using B = X;
 // CHECK:  TypeAliasDecl
 // CHECK-NEXT: `-ElaboratedType {{.*}} 

[clang] [Clang] Fix handling of brace ellison when building deduction guides (PR #94889)

2024-06-11 Thread Haojian Wu via cfe-commits


@@ -335,3 +335,73 @@ namespace TTP {
 // CHECK-NEXT:  `-TemplateArgument type 'T':'type-parameter-0-0'{{$}}
 // CHECK-NEXT:`-TemplateTypeParmType {{.+}} 'T' dependent depth 0 
index 0{{$}}
 // CHECK-NEXT:  `-TemplateTypeParm {{.+}} 'T'{{$}}
+
+namespace GH64625 {
+
+template  struct X {
+  T t[2];
+};
+
+X x = {{1, 2}}, y = {1, 2};

hokein wrote:

nit: `y = {1, 2}` is already working today. Let's just add the problematic test 
cases.

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


[clang] [Clang] Fix handling of brace ellison when building deduction guides (PR #94889)

2024-06-11 Thread Haojian Wu via cfe-commits


@@ -10918,22 +10944,24 @@ QualType 
Sema::DeduceTemplateSpecializationFromInitializer(
   if (!(RD->getDefinition() && RD->isAggregate()))
 return;
   QualType Ty = Context.getRecordType(RD);
-  SmallVector ElementTypes;
-
-  InitListChecker CheckInitList(*this, Entity, ListInit, Ty, ElementTypes);
-  if (!CheckInitList.HadError()) {
+  auto BuildAggregateDeductionGuide = [&](MutableArrayRef
+  ElementTypes,
+  bool BracedVersion = false) {
+if (ElementTypes.empty())
+  return;
 // C++ [over.match.class.deduct]p1.8:
 //   if e_i is of array type and x_i is a braced-init-list, T_i is an
 //   rvalue reference to the declared type of e_i and
 // C++ [over.match.class.deduct]p1.9:
-//   if e_i is of array type and x_i is a bstring-literal, T_i is an
+//   if e_i is of array type and x_i is a string-literal, T_i is an
 //   lvalue reference to the const-qualified declared type of e_i and
 // C++ [over.match.class.deduct]p1.10:
 //   otherwise, T_i is the declared type of e_i
-for (int I = 0, E = ListInit->getNumInits();
+for (int I = 0, E = BracedVersion ? ElementTypes.size()
+  : ListInit->getNumInits();
  I < E && !isa(ElementTypes[I]); ++I)
   if (ElementTypes[I]->isArrayType()) {
-if (isa(ListInit->getInit(I)))
+if (isa(ListInit->getInit(I)))

hokein wrote:

Is there any justification for `a designated-initializer-list is also a 
braced-init-list`? I didn't find any related words in the standard, and I'm not 
sure this is correct, they at least have different forms per the standard 
grammar.

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


[clang] [Clang] Fix handling of brace ellison when building deduction guides (PR #94889)

2024-06-11 Thread Haojian Wu via cfe-commits


@@ -335,3 +335,73 @@ namespace TTP {
 // CHECK-NEXT:  `-TemplateArgument type 'T':'type-parameter-0-0'{{$}}
 // CHECK-NEXT:`-TemplateTypeParmType {{.+}} 'T' dependent depth 0 
index 0{{$}}
 // CHECK-NEXT:  `-TemplateTypeParm {{.+}} 'T'{{$}}
+
+namespace GH64625 {
+
+template  struct X {

hokein wrote:

Can you add a test with multiple array members? like

```
template  struct X {
  T t1[2];
  T t2[3];
};

X x = {{1, 2}, {3, 4, 5}};
```

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


[clang] [Clang] Fix handling of brace ellison when building deduction guides (PR #94889)

2024-06-11 Thread Haojian Wu via cfe-commits


@@ -305,14 +305,32 @@ namespace {
 /// structured list even in 'verify only' mode, so that we can track which
 /// elements need 'empty' initializtion.
 class InitListChecker {
+public:
+  struct CandidateParamTypesForAggregateDeduction {

hokein wrote:

nit: instead of using two pointers pointing to the external storage, I'd 
suggest storing value in this struct, and use a pointer of 
`CandidateParamTypesForAggregateDeduction` in the `InitListChecker`.

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


[clang] [Clang] Fix handling of brace ellison when building deduction guides (PR #94889)

2024-06-11 Thread Haojian Wu via cfe-commits


@@ -10918,22 +10944,24 @@ QualType 
Sema::DeduceTemplateSpecializationFromInitializer(
   if (!(RD->getDefinition() && RD->isAggregate()))
 return;
   QualType Ty = Context.getRecordType(RD);
-  SmallVector ElementTypes;
-
-  InitListChecker CheckInitList(*this, Entity, ListInit, Ty, ElementTypes);
-  if (!CheckInitList.HadError()) {
+  auto BuildAggregateDeductionGuide = [&](MutableArrayRef
+  ElementTypes,
+  bool BracedVersion = false) {
+if (ElementTypes.empty())
+  return;
 // C++ [over.match.class.deduct]p1.8:
 //   if e_i is of array type and x_i is a braced-init-list, T_i is an
 //   rvalue reference to the declared type of e_i and
 // C++ [over.match.class.deduct]p1.9:
-//   if e_i is of array type and x_i is a bstring-literal, T_i is an
+//   if e_i is of array type and x_i is a string-literal, T_i is an
 //   lvalue reference to the const-qualified declared type of e_i and
 // C++ [over.match.class.deduct]p1.10:
 //   otherwise, T_i is the declared type of e_i
-for (int I = 0, E = ListInit->getNumInits();
+for (int I = 0, E = BracedVersion ? ElementTypes.size()
+  : ListInit->getNumInits();

hokein wrote:

this loop becomes harder to reason about, the iterator `I` is used to access 
two containers `ListInit`, `ElementTypes`, can we add some assertions to make 
sure we don't have out-of-bound issues here?

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


[clang] [Clang] Substitute for the type aliases inside of a CTAD guide (PR #94740)

2024-06-11 Thread Haojian Wu via cfe-commits


@@ -2630,7 +2711,8 @@ struct ConvertConstructorToDeductionGuideTransform {
 
   ParmVarDecl *transformFunctionTypeParam(
   ParmVarDecl *OldParam, MultiLevelTemplateArgumentList ,
-  llvm::SmallVectorImpl ) {
+  llvm::SmallVectorImpl ,
+  bool TransformingOuterPatterns = false) {

hokein wrote:

nit: remove this default argument for `TransformingOuterPatterns`, there is 
only 2 places calling this function (one for `true`, the other one for `false`)

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


[clang] [Clang] Substitute for the type aliases inside of a CTAD guide (PR #94740)

2024-06-11 Thread Haojian Wu via cfe-commits


@@ -2220,23 +2220,103 @@ namespace {
 class ExtractTypeForDeductionGuide
   : public TreeTransform {
   llvm::SmallVectorImpl 
+  ClassTemplateDecl *NestedPattern;
+  const MultiLevelTemplateArgumentList *OuterInstantiationArgs;
 
 public:
   typedef TreeTransform Base;
   ExtractTypeForDeductionGuide(
   Sema ,
-  llvm::SmallVectorImpl )
-  : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs) {}
+  llvm::SmallVectorImpl ,
+  ClassTemplateDecl *NestedPattern,
+  const MultiLevelTemplateArgumentList *OuterInstantiationArgs)
+  : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs),
+NestedPattern(NestedPattern),
+OuterInstantiationArgs(OuterInstantiationArgs) {}
 
   TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(TSI); }
 
+  /// Returns true if it's safe to substitute \p Typedef with
+  /// \p OuterInstantiationArgs.
+  bool mightReferToOuterTemplateParameters(TypedefNameDecl *Typedef) {
+if (!NestedPattern)
+  return false;
+
+static auto WalkUp = [](DeclContext *DC, DeclContext *TargetDC) {
+  if (DC->Equals(TargetDC))
+return true;
+  while (DC->isRecord()) {
+if (DC->Equals(TargetDC))
+  return true;
+DC = DC->getParent();
+  }
+  return false;
+};
+
+if (WalkUp(Typedef->getDeclContext(), NestedPattern->getTemplatedDecl()))
+  return true;
+if (WalkUp(NestedPattern->getTemplatedDecl(), Typedef->getDeclContext()))
+  return true;
+return false;
+  }
+
+  QualType
+  RebuildTemplateSpecializationType(TemplateName Template,
+SourceLocation TemplateNameLoc,
+TemplateArgumentListInfo ) {
+if (!OuterInstantiationArgs ||
+!isa_and_present(Template.getAsTemplateDecl()))
+  return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
+ TemplateArgs);
+
+auto *TATD = cast(Template.getAsTemplateDecl());
+auto *Pattern = TATD;
+while (Pattern->getInstantiatedFromMemberTemplate())
+  Pattern = Pattern->getInstantiatedFromMemberTemplate();
+if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
+  return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
+ TemplateArgs);
+
+Decl *NewD = SemaRef.SubstDecl(
+TATD, SemaRef.getASTContext().getTranslationUnitDecl(),
+*OuterInstantiationArgs);
+if (!NewD)
+  return QualType();
+
+auto *NewTATD = cast(NewD);
+MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());
+
+return Base::RebuildTemplateSpecializationType(
+TemplateName(NewTATD), TemplateNameLoc, TemplateArgs);
+  }
+
   QualType TransformTypedefType(TypeLocBuilder , TypedefTypeLoc TL) {
 ASTContext  = SemaRef.getASTContext();
 TypedefNameDecl *OrigDecl = TL.getTypedefNameDecl();
 TypedefNameDecl *Decl = OrigDecl;
 // Transform the underlying type of the typedef and clone the Decl only if
 // the typedef has a dependent context.
-if (OrigDecl->getDeclContext()->isDependentContext()) {
+bool InDependentContext = OrigDecl->getDeclContext()->isDependentContext();
+
+// A typedef/alias Decl within the NestedPattern may reference the outer
+// template parameters. They're substituted with corresponding 
instantiation
+// arguments here and in RebuildTemplateSpecializationType() above.
+// Otherwise, we would have a CTAD guide with "dangling" template
+// parameters.
+// For example,
+//   template  struct Outer {
+// using Alias = S;
+// template  struct Inner {
+//   Inner(Alias);
+// };
+//   };
+if (OuterInstantiationArgs && InDependentContext) {
+  Decl = cast_if_present(SemaRef.SubstDecl(
+  OrigDecl, Context.getTranslationUnitDecl(), 
*OuterInstantiationArgs));

hokein wrote:

and here as well.

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


[clang] [Clang] Substitute for the type aliases inside of a CTAD guide (PR #94740)

2024-06-11 Thread Haojian Wu via cfe-commits


@@ -2220,23 +2220,103 @@ namespace {
 class ExtractTypeForDeductionGuide
   : public TreeTransform {
   llvm::SmallVectorImpl 
+  ClassTemplateDecl *NestedPattern;
+  const MultiLevelTemplateArgumentList *OuterInstantiationArgs;
 
 public:
   typedef TreeTransform Base;
   ExtractTypeForDeductionGuide(
   Sema ,
-  llvm::SmallVectorImpl )
-  : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs) {}
+  llvm::SmallVectorImpl ,
+  ClassTemplateDecl *NestedPattern,
+  const MultiLevelTemplateArgumentList *OuterInstantiationArgs)
+  : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs),
+NestedPattern(NestedPattern),
+OuterInstantiationArgs(OuterInstantiationArgs) {}
 
   TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(TSI); }
 
+  /// Returns true if it's safe to substitute \p Typedef with
+  /// \p OuterInstantiationArgs.
+  bool mightReferToOuterTemplateParameters(TypedefNameDecl *Typedef) {
+if (!NestedPattern)
+  return false;
+
+static auto WalkUp = [](DeclContext *DC, DeclContext *TargetDC) {
+  if (DC->Equals(TargetDC))
+return true;
+  while (DC->isRecord()) {
+if (DC->Equals(TargetDC))
+  return true;
+DC = DC->getParent();
+  }
+  return false;
+};
+
+if (WalkUp(Typedef->getDeclContext(), NestedPattern->getTemplatedDecl()))
+  return true;
+if (WalkUp(NestedPattern->getTemplatedDecl(), Typedef->getDeclContext()))
+  return true;
+return false;
+  }
+
+  QualType
+  RebuildTemplateSpecializationType(TemplateName Template,
+SourceLocation TemplateNameLoc,
+TemplateArgumentListInfo ) {
+if (!OuterInstantiationArgs ||
+!isa_and_present(Template.getAsTemplateDecl()))
+  return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
+ TemplateArgs);
+
+auto *TATD = cast(Template.getAsTemplateDecl());
+auto *Pattern = TATD;
+while (Pattern->getInstantiatedFromMemberTemplate())
+  Pattern = Pattern->getInstantiatedFromMemberTemplate();
+if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
+  return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
+ TemplateArgs);
+
+Decl *NewD = SemaRef.SubstDecl(
+TATD, SemaRef.getASTContext().getTranslationUnitDecl(),
+*OuterInstantiationArgs);
+if (!NewD)
+  return QualType();
+
+auto *NewTATD = cast(NewD);
+MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());
+
+return Base::RebuildTemplateSpecializationType(
+TemplateName(NewTATD), TemplateNameLoc, TemplateArgs);
+  }
+
   QualType TransformTypedefType(TypeLocBuilder , TypedefTypeLoc TL) {
 ASTContext  = SemaRef.getASTContext();
 TypedefNameDecl *OrigDecl = TL.getTypedefNameDecl();
 TypedefNameDecl *Decl = OrigDecl;
 // Transform the underlying type of the typedef and clone the Decl only if
 // the typedef has a dependent context.
-if (OrigDecl->getDeclContext()->isDependentContext()) {
+bool InDependentContext = OrigDecl->getDeclContext()->isDependentContext();
+
+// A typedef/alias Decl within the NestedPattern may reference the outer
+// template parameters. They're substituted with corresponding 
instantiation
+// arguments here and in RebuildTemplateSpecializationType() above.
+// Otherwise, we would have a CTAD guide with "dangling" template
+// parameters.
+// For example,
+//   template  struct Outer {
+// using Alias = S;
+// template  struct Inner {
+//   Inner(Alias);
+// };
+//   };
+if (OuterInstantiationArgs && InDependentContext) {
+  Decl = cast_if_present(SemaRef.SubstDecl(

hokein wrote:

We will perform the substitution even if the typedef/alias decl doesn't have 
any dependent template parameter references (e.g. `using Alias = S`.), 
this seems unnecessary.

A simple idea to avoid it is to perform the substitution only if the type of 
`TypedefNameDecl` is dependent.

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


[clang] [Clang] Substitute for the type aliases inside of a CTAD guide (PR #94740)

2024-06-11 Thread Haojian Wu via cfe-commits

https://github.com/hokein commented:

Looks roughly good to me.

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


[clang] [Clang] Substitute for the type aliases inside of a CTAD guide (PR #94740)

2024-06-11 Thread Haojian Wu via cfe-commits

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


[clang] [Clang] Substitute for the type aliases inside of a CTAD guide (PR #94740)

2024-06-11 Thread Haojian Wu via cfe-commits


@@ -16,3 +16,73 @@ using T = A::B;
 
 using Copy = decltype(copy);
 using Copy = A::B;
+
+namespace GH94614 {
+
+template  struct S {};

hokein wrote:

I wonder whether it is feasible to add an ast-dump test for this issue, I find 
seeing and verifying the shape of AST deduction guide is clearer. However, the 
ast-dump doesn't seem to dump much information about the type of the function 
parameter decl, which is the information we want to verify. 

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


[clang] [Clang] Substitute for the type aliases inside of a CTAD guide (PR #94740)

2024-06-11 Thread Haojian Wu via cfe-commits


@@ -2220,23 +2220,103 @@ namespace {
 class ExtractTypeForDeductionGuide
   : public TreeTransform {
   llvm::SmallVectorImpl 
+  ClassTemplateDecl *NestedPattern;
+  const MultiLevelTemplateArgumentList *OuterInstantiationArgs;
 
 public:
   typedef TreeTransform Base;
   ExtractTypeForDeductionGuide(
   Sema ,
-  llvm::SmallVectorImpl )
-  : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs) {}
+  llvm::SmallVectorImpl ,
+  ClassTemplateDecl *NestedPattern,
+  const MultiLevelTemplateArgumentList *OuterInstantiationArgs)
+  : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs),
+NestedPattern(NestedPattern),
+OuterInstantiationArgs(OuterInstantiationArgs) {}
 
   TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(TSI); }
 
+  /// Returns true if it's safe to substitute \p Typedef with
+  /// \p OuterInstantiationArgs.
+  bool mightReferToOuterTemplateParameters(TypedefNameDecl *Typedef) {
+if (!NestedPattern)
+  return false;
+
+static auto WalkUp = [](DeclContext *DC, DeclContext *TargetDC) {
+  if (DC->Equals(TargetDC))
+return true;
+  while (DC->isRecord()) {
+if (DC->Equals(TargetDC))
+  return true;
+DC = DC->getParent();
+  }
+  return false;
+};
+
+if (WalkUp(Typedef->getDeclContext(), NestedPattern->getTemplatedDecl()))
+  return true;
+if (WalkUp(NestedPattern->getTemplatedDecl(), Typedef->getDeclContext()))
+  return true;
+return false;
+  }
+
+  QualType
+  RebuildTemplateSpecializationType(TemplateName Template,
+SourceLocation TemplateNameLoc,
+TemplateArgumentListInfo ) {
+if (!OuterInstantiationArgs ||
+!isa_and_present(Template.getAsTemplateDecl()))
+  return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
+ TemplateArgs);
+
+auto *TATD = cast(Template.getAsTemplateDecl());
+auto *Pattern = TATD;
+while (Pattern->getInstantiatedFromMemberTemplate())
+  Pattern = Pattern->getInstantiatedFromMemberTemplate();
+if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
+  return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
+ TemplateArgs);
+
+Decl *NewD = SemaRef.SubstDecl(
+TATD, SemaRef.getASTContext().getTranslationUnitDecl(),

hokein wrote:

Passing the `TranslationUnitDecl` seems wrong -- the NewD will be attached to 
the TU, I think we should use the `DC` member in 
`ConvertConstructorToDeductionGuideTransform`.

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


[clang-tools-extra] [clangd] Use clang_target_link_libraries() for clang libs (PR #94937)

2024-06-10 Thread Haojian Wu via cfe-commits

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


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


[clang] 6fe5428 - [Flang] Handle the newly-added "Reserved" FramePointerKind for 1a5239251ead73ee57f4e2f7fc93433ac7cf18b1

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

Author: Haojian Wu
Date: 2024-06-07T12:49:41+02:00
New Revision: 6fe5428ecbd18aa263417a244c0850b1271617c0

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

LOG: [Flang] Handle the newly-added "Reserved" FramePointerKind for 
1a5239251ead73ee57f4e2f7fc93433ac7cf18b1

Added: 


Modified: 
clang/lib/Driver/ToolChains/Flang.cpp

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Flang.cpp 
b/clang/lib/Driver/ToolChains/Flang.cpp
index 9609a1dc65c09..42b45dba2bd31 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -802,6 +802,9 @@ void Flang::ConstructJob(Compilation , const JobAction 
,
   case CodeGenOptions::FramePointerKind::None:
 FPKeepKindStr = "-mframe-pointer=none";
 break;
+   case CodeGenOptions::FramePointerKind::Reserved:
+FPKeepKindStr = "-mframe-pointer=reserved";
+break;
   case CodeGenOptions::FramePointerKind::NonLeaf:
 FPKeepKindStr = "-mframe-pointer=non-leaf";
 break;



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


[clang] 7939312 - Fix -Wunused-variable in SemaAMDGPU.cpp in release build, NFC

2024-06-06 Thread Haojian Wu via cfe-commits

Author: Haojian Wu
Date: 2024-06-06T15:48:23+02:00
New Revision: 79393124ff74aaaf6a43f7c88e67fd76a6e44239

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

LOG: Fix -Wunused-variable in SemaAMDGPU.cpp in release build, NFC

Added: 


Modified: 
clang/lib/Sema/SemaAMDGPU.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaAMDGPU.cpp b/clang/lib/Sema/SemaAMDGPU.cpp
index 51d4f0d3d964..d11bc9eec330 100644
--- a/clang/lib/Sema/SemaAMDGPU.cpp
+++ b/clang/lib/Sema/SemaAMDGPU.cpp
@@ -31,7 +31,8 @@ bool SemaAMDGPU::CheckAMDGCNBuiltinFunctionCall(unsigned 
BuiltinID,
 constexpr const int SizeIdx = 2;
 llvm::APSInt Size;
 Expr *ArgExpr = TheCall->getArg(SizeIdx);
-ExprResult R = SemaRef.VerifyIntegerConstantExpression(ArgExpr, );
+[[maybe_unused]] ExprResult R =
+SemaRef.VerifyIntegerConstantExpression(ArgExpr, );
 assert(!R.isInvalid());
 switch (Size.getSExtValue()) {
 case 1:



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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-06-05 Thread Haojian Wu via cfe-commits

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

I'm landing it now to unblock our integration. I'm happy to address any post 
comments.

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

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

>From 8457c4aa1758d10188da5978d30d2d1ed505e01e Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 15:46:56 +0200
Subject: [PATCH 1/4] Fix clang reject valid C++ code after
 d999ce0302f06d250f6d496b56a5a5f2dc331e61

The incremental processing mode doesn't seem to work well for C++.
---
 clang/lib/Sema/SemaDecl.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a6734ef8c30aa..4b9b735f1cfb4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2288,7 +2288,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
 // Partial translation units that are created in incremental processing 
must
 // not clean up the IdResolver because PTUs should take into account the
 // declarations that came from previous PTUs.
-if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC)
+if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC ||
+getLangOpts().CPlusPlus)
   IdResolver.RemoveDecl(D);
 
 // Warn on it if we are shadowing a declaration.

>From 5d3e60cc5839fece4f3f8d8d158ae562d7604580 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 20:34:30 +0200
Subject: [PATCH 2/4] Fix more

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

diff --git a/clang/lib/Interpreter/IncrementalParser.cpp 
b/clang/lib/Interpreter/IncrementalParser.cpp
index 5bc8385d874a1..bbc6d3addb085 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -413,7 +413,9 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit 
) {
 if (!ND)
   continue;
 // Check if we need to clean up the IdResolver chain.
-if (ND->getDeclName().getFETokenInfo())
+if (ND->getDeclName().getFETokenInfo() &&
+CI->getPreprocessor().isIncrementalProcessingEnabled() &&
+!D->getLangOpts().ObjC && !D->getLangOpts().CPlusPlus)
   getCI()->getSema().IdResolver.RemoveDecl(ND);
   }
 }

>From 59b94757009ceae2a7fe685afd42d933b18cf3dc Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 21:11:25 +0200
Subject: [PATCH 3/4] address review comment.

---
 clang/lib/Interpreter/IncrementalParser.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/Interpreter/IncrementalParser.cpp 
b/clang/lib/Interpreter/IncrementalParser.cpp
index bbc6d3addb085..f709875379d7b 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -414,7 +414,6 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit 
) {
   continue;
 // Check if we need to clean up the IdResolver chain.
 if (ND->getDeclName().getFETokenInfo() &&
-CI->getPreprocessor().isIncrementalProcessingEnabled() &&
 !D->getLangOpts().ObjC && !D->getLangOpts().CPlusPlus)
   getCI()->getSema().IdResolver.RemoveDecl(ND);
   }

>From 8894026730a65e9f3f352544d3a04251d2b246f1 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 21:30:02 +0200
Subject: [PATCH 4/4] clang-format

---
 clang/lib/Interpreter/IncrementalParser.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Interpreter/IncrementalParser.cpp 
b/clang/lib/Interpreter/IncrementalParser.cpp
index f709875379d7b..a8d0294fb6151 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -413,8 +413,8 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit 
) {
 if (!ND)
   continue;
 // Check if we need to clean up the IdResolver chain.
-if (ND->getDeclName().getFETokenInfo() &&
-!D->getLangOpts().ObjC && !D->getLangOpts().CPlusPlus)
+if (ND->getDeclName().getFETokenInfo() && !D->getLangOpts().ObjC &&
+!D->getLangOpts().CPlusPlus)
   getCI()->getSema().IdResolver.RemoveDecl(ND);
   }
 }

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits


@@ -413,7 +413,9 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit 
) {
 if (!ND)
   continue;
 // Check if we need to clean up the IdResolver chain.
-if (ND->getDeclName().getFETokenInfo())
+if (ND->getDeclName().getFETokenInfo() &&
+CI->getPreprocessor().isIncrementalProcessingEnabled() &&

hokein wrote:

good point. Removed.

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

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

>From 8457c4aa1758d10188da5978d30d2d1ed505e01e Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 15:46:56 +0200
Subject: [PATCH 1/3] Fix clang reject valid C++ code after
 d999ce0302f06d250f6d496b56a5a5f2dc331e61

The incremental processing mode doesn't seem to work well for C++.
---
 clang/lib/Sema/SemaDecl.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a6734ef8c30aa..4b9b735f1cfb4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2288,7 +2288,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
 // Partial translation units that are created in incremental processing 
must
 // not clean up the IdResolver because PTUs should take into account the
 // declarations that came from previous PTUs.
-if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC)
+if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC ||
+getLangOpts().CPlusPlus)
   IdResolver.RemoveDecl(D);
 
 // Warn on it if we are shadowing a declaration.

>From 5d3e60cc5839fece4f3f8d8d158ae562d7604580 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 20:34:30 +0200
Subject: [PATCH 2/3] Fix more

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

diff --git a/clang/lib/Interpreter/IncrementalParser.cpp 
b/clang/lib/Interpreter/IncrementalParser.cpp
index 5bc8385d874a1..bbc6d3addb085 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -413,7 +413,9 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit 
) {
 if (!ND)
   continue;
 // Check if we need to clean up the IdResolver chain.
-if (ND->getDeclName().getFETokenInfo())
+if (ND->getDeclName().getFETokenInfo() &&
+CI->getPreprocessor().isIncrementalProcessingEnabled() &&
+!D->getLangOpts().ObjC && !D->getLangOpts().CPlusPlus)
   getCI()->getSema().IdResolver.RemoveDecl(ND);
   }
 }

>From 59b94757009ceae2a7fe685afd42d933b18cf3dc Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 21:11:25 +0200
Subject: [PATCH 3/3] address review comment.

---
 clang/lib/Interpreter/IncrementalParser.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/Interpreter/IncrementalParser.cpp 
b/clang/lib/Interpreter/IncrementalParser.cpp
index bbc6d3addb085..f709875379d7b 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -414,7 +414,6 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit 
) {
   continue;
 // Check if we need to clean up the IdResolver chain.
 if (ND->getDeclName().getFETokenInfo() &&
-CI->getPreprocessor().isIncrementalProcessingEnabled() &&
 !D->getLangOpts().ObjC && !D->getLangOpts().CPlusPlus)
   getCI()->getSema().IdResolver.RemoveDecl(ND);
   }

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

I have update a new version, please take a second look.

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

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

>From 8457c4aa1758d10188da5978d30d2d1ed505e01e Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 15:46:56 +0200
Subject: [PATCH 1/2] Fix clang reject valid C++ code after
 d999ce0302f06d250f6d496b56a5a5f2dc331e61

The incremental processing mode doesn't seem to work well for C++.
---
 clang/lib/Sema/SemaDecl.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a6734ef8c30aa..4b9b735f1cfb4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2288,7 +2288,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
 // Partial translation units that are created in incremental processing 
must
 // not clean up the IdResolver because PTUs should take into account the
 // declarations that came from previous PTUs.
-if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC)
+if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC ||
+getLangOpts().CPlusPlus)
   IdResolver.RemoveDecl(D);
 
 // Warn on it if we are shadowing a declaration.

>From 5d3e60cc5839fece4f3f8d8d158ae562d7604580 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 20:34:30 +0200
Subject: [PATCH 2/2] Fix more

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

diff --git a/clang/lib/Interpreter/IncrementalParser.cpp 
b/clang/lib/Interpreter/IncrementalParser.cpp
index 5bc8385d874a1..bbc6d3addb085 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -413,7 +413,9 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit 
) {
 if (!ND)
   continue;
 // Check if we need to clean up the IdResolver chain.
-if (ND->getDeclName().getFETokenInfo())
+if (ND->getDeclName().getFETokenInfo() &&
+CI->getPreprocessor().isIncrementalProcessingEnabled() &&
+!D->getLangOpts().ObjC && !D->getLangOpts().CPlusPlus)
   getCI()->getSema().IdResolver.RemoveDecl(ND);
   }
 }

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

> Oh, we need to adjust 
> https://github.com/root-project/root/blob/be5d34934de883270683030b3af2cd1195d17ea8/cmake/modules/RootMacros.cmake#L272
>  to skip in case of C++...

The link points to an irrelevant project, I assume you mean here 
https://github.com/llvm/llvm-project/blob/main/clang/lib/Interpreter/IncrementalParser.cpp#L416?
 If we need to skip for C++, I think we should do it for ObjectiveC as well, 
like

```
if (ND->getDeclName().getFETokenInfo()  &&
!(!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC || 
getLangOpts().CPlusPlus)) {
   ...
}
```

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

unfortunately, this seems to break an existing test:

```
   OK ] InterpreterTest.IncrementalInputTopLevelDecls (66 ms)
[ RUN  ] InterpreterTest.Errors
ClangReplInterpreterTests: 
/usr/local/google/home/hokein/workspace/llvm-project/clang/lib/Sema/IdentifierResolver.cpp:228:
 void clang::IdentifierResolver::RemoveDecl(NamedDecl *): Assertion `Ptr && 
"Didn't find this decl on its identifier's chain!"' failed.
 #0 0x5591835285e1 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
(tools/clang/unittests/Interpreter/ClangReplInterpreterTests+0xa4e45e1)
 #1 0x559183528b9b PrintStackTraceSignalHandler(void*) Signals.cpp:0:0
 #2 0x559183526356 llvm::sys::RunSignalHandlers() 
(tools/clang/unittests/Interpreter/ClangReplInterpreterTests+0xa4e2356)
 #3 0x559183529d35 SignalHandler(int) Signals.cpp:0:0
 #4 0x7f5baf25a510 (/lib/x86_64-linux-gnu/libc.so.6+0x3c510)
 #5 0x7f5baf2a816
```

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

https://github.com/hokein created 
https://github.com/llvm/llvm-project/pull/94471



The incremental processing mode doesn't seem to work well for C++.

>From 8457c4aa1758d10188da5978d30d2d1ed505e01e Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 15:46:56 +0200
Subject: [PATCH] Fix clang reject valid C++ code after
 d999ce0302f06d250f6d496b56a5a5f2dc331e61

The incremental processing mode doesn't seem to work well for C++.
---
 clang/lib/Sema/SemaDecl.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a6734ef8c30aa..4b9b735f1cfb4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2288,7 +2288,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
 // Partial translation units that are created in incremental processing 
must
 // not clean up the IdResolver because PTUs should take into account the
 // declarations that came from previous PTUs.
-if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC)
+if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC ||
+getLangOpts().CPlusPlus)
   IdResolver.RemoveDecl(D);
 
 // Warn on it if we are shadowing a declaration.

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

> I want to somehow record this breakage in the form of a test for our future 
> selves when decide to revisit this workaround-looking code.

This is the processed file  
https://gist.github.com/hokein/e4a5881329c3956494afa2de7d350476.

> I am a bit overwhelmed right now, are you willing to open a PR with that 
> change so we can merge it -- otherwise I could look later this week :(

Sure, I will prepare one.

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

> Out of curiosity, in what context you use -fincremental-extensions?

The code snippet I provided is extracted from our internal test. We have an 
internal clang-tool (with the `incremental-extensions` on) to generate headers 

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

Thanks for the prompt response. I think limiting it to C-only will fix the 
issue (note that there is no `C` in `LangOpts`, you may want to use 
`!getLangOpts().CPlusPlus` to exclude C++).

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

@vgvassilev 

The reland d999ce0302f06d250f6d496b56a5a5f2dc331e61 makes the clang reject the 
valid code now:

```
$ cat /tmp/t33.cpp
#include 
#include 

int main() {

}

  
$  ./bin/clang -Xclang -fsyntax-only -Xclang=-fincremental-extensions 
-stdlib=libc++ /tmp/t33.cpp  <<<
In file included from /tmp/t33.cpp:2:
In file included from /usr/include/c++/v1/algorithm:1712:
In file included from /usr/include/c++/v1/memory:877:
In file included from /usr/include/c++/v1/iterator:684:
In file included from /usr/include/c++/v1/__iterator/common_iterator.h:22:
/usr/include/c++/v1/variant:1024:43: error: use of undeclared identifier 
'__arg'; did you mean '_pthread_cleanup_buffer::__arg'?
 1024 |   } __impl{this, _VSTD::forward<_Arg>(__arg)};
  |   ^
/usr/include/pthread.h:162:9: note: '_pthread_cleanup_buffer::__arg' declared 
here
  162 |   void *__arg;/* Its argument.  */
  | ^
In file included from /tmp/t33.cpp:2:
In file included from /usr/include/c++/v1/algorithm:1861:
In file included from 
/usr/include/c++/v1/__algorithm/ranges_stable_partition.h:15:
/usr/include/c++/v1/__algorithm/stable_partition.h:246:18: error: use of 
undeclared label '__second_half_done'
  246 | goto __second_half_done;
  |  ^
2 errors generated.
```

Can you take a look?

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-06-05 Thread Haojian Wu via cfe-commits

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

>From 3ce87797dbc36ae792b4d82077cd8f27f1eee53e Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 25 Mar 2024 15:10:51 +0100
Subject: [PATCH] [clang] Implement a bitwise_copyable builtin type trait.

This patch implements a `__is_bitwise_copyable` builtin in clang.

The bitwise copyable types act as the trivially copyable types, but
they support a wider range of types (e.g. classes with virtual methods) --
their underlying types can be safely copied by `memcopy` or `memmove`,
the clang compiler guarantees that both source and destination objects
have the same *object* representations after the copy operation, and the
lifetime of the destination object implicitly starts.

A particular use case of this builtin is to clone an object via memcopy
(without running the constructor):

```
Message* clone(const Message* src, char* buffer, int size) {
  if constexpr __is_bitwise_copyable(Message) {
// bitwise copy to buffer
__builtin_memcpy(buffer, src, size);
// using __builtin_launder to prevent miscompile for 
-fstrict-vtable-pointers.
return __builtin_launder(reinterpret_cast(buffer));
  }
  // Fallback the operator new, which calls the constructor to start the 
lifetime.
  return new(buffer) Message(src);
}
```

Note that the definition of bitwise copyable is not tied to the Rule Of
Five, so users of this builtin must guarantee that program semantic constraints
are satisfied, e.g. no double resource deallocations.

Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy
---
 clang/docs/LanguageExtensions.rst | 24 
 clang/docs/ReleaseNotes.rst   |  3 ++
 clang/include/clang/AST/Type.h| 14 +++
 clang/include/clang/Basic/TokenKinds.def  |  2 +
 clang/lib/AST/Type.cpp| 37 +++
 clang/lib/Sema/SemaExprCXX.cpp|  3 ++
 ...builtin-is-bitwise-cloneable-fsanitize.cpp | 34 +
 .../SemaCXX/builtin-is-bitwise-cloneable.cpp  |  8 
 clang/test/SemaObjCXX/arc-type-traits.mm  |  9 +
 9 files changed, 134 insertions(+)
 create mode 100644 
clang/test/SemaCXX/builtin-is-bitwise-cloneable-fsanitize.cpp
 create mode 100644 clang/test/SemaCXX/builtin-is-bitwise-cloneable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 46f99d0bbdd06..a49e4122ffc10 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -4016,6 +4016,30 @@ Note that the `size` argument must be a compile time 
constant.
 
 Note that this intrinsic cannot yet be called in a ``constexpr`` context.
 
+``__is_bitwise_cloneable``
+--
+
+A type trait is used to check whether a type can be safely copied by memcpy.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  bool __is_bitwise_cloneable(Type)
+
+**Description**:
+
+Objects of bitwise cloneable types can be bitwise copied by memcpy/memmove. The
+Clang compiler warrants that this behavior is well defined, and won't be
+broken by compiler optimizations and sanitizers.
+
+For implicit-lifetime types, the lifetime of the new object is implicitly
+started after the copy. For other types (e.g., classes with virtual methods),
+the lifetime isn't started, and using the object results in undefined behavior
+according to the C++ Standard.
+
+This builtin can be used in constant expressions.
+
 Atomic Min/Max builtins with memory ordering
 
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 39a9013c75a41..3d54144bf9206 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,9 @@ Non-comprehensive list of changes in this release
   ``-Winvalid-constexpr`` is not enabled for the function definition, which
   should result in mild compile-time performance improvements.
 
+- Added ``__is_bitwise_cloneable`` which is used to check whether a type
+  can be safely copied by memcpy/memmove.
+
 New Compiler Flags
 --
 - ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 263b632df23ce..9eb3f6c09e3d3 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1120,6 +1120,20 @@ class QualType {
   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
   bool isTriviallyCopyableType(const ASTContext ) const;
 
+  /// Return true if the type is safe to bitwise copy using memcpy/memmove.
+  ///
+  /// This is an extension in clang: bitwise cloneable types act as trivially
+  /// copyable types, meaning their underlying bytes can be safely copied by
+  /// memcpy or memmove. After the copy, the destination object has the same
+  /// object representation.
+  ///
+  /// However, there are cases where it is not 

[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-06-05 Thread Haojian Wu via cfe-commits

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

>From 0eec9639530a137da6c4c4b2cc4249a3f9dd9939 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 25 Mar 2024 15:10:51 +0100
Subject: [PATCH] [clang] Implement a bitwise_copyable builtin type trait.

This patch implements a `__is_bitwise_copyable` builtin in clang.

The bitwise copyable types act as the trivially copyable types, but
they support a wider range of types (e.g. classes with virtual methods) --
their underlying types can be safely copied by `memcopy` or `memmove`,
the clang compiler guarantees that both source and destination objects
have the same *object* representations after the copy operation, and the
lifetime of the destination object implicitly starts.

A particular use case of this builtin is to clone an object via memcopy
(without running the constructor):

```
Message* clone(const Message* src, char* buffer, int size) {
  if constexpr __is_bitwise_copyable(Message) {
// bitwise copy to buffer
__builtin_memcpy(buffer, src, size);
// using __builtin_launder to prevent miscompile for 
-fstrict-vtable-pointers.
return __builtin_launder(reinterpret_cast(buffer));
  }
  // Fallback the operator new, which calls the constructor to start the 
lifetime.
  return new(buffer) Message(src);
}
```

Note that the definition of bitwise copyable is not tied to the Rule Of
Five, so users of this builtin must guarantee that program semantic constraints
are satisfied, e.g. no double resource deallocations.

Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy
---
 clang/docs/LanguageExtensions.rst | 24 
 clang/docs/ReleaseNotes.rst   |  3 ++
 clang/include/clang/AST/Type.h| 14 +++
 clang/include/clang/Basic/TokenKinds.def  |  2 +
 clang/lib/AST/Type.cpp| 37 +++
 clang/lib/Sema/SemaExprCXX.cpp|  3 ++
 ...builtin-is-bitwise-cloneable-fsanitize.cpp | 34 +
 .../SemaCXX/builtin-is-bitwise-cloneable.cpp  |  8 
 clang/test/SemaObjCXX/arc-type-traits.mm  |  9 +
 9 files changed, 134 insertions(+)
 create mode 100644 
clang/test/SemaCXX/builtin-is-bitwise-cloneable-fsanitize.cpp
 create mode 100644 clang/test/SemaCXX/builtin-is-bitwise-cloneable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 46f99d0bbdd06..a49e4122ffc10 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -4016,6 +4016,30 @@ Note that the `size` argument must be a compile time 
constant.
 
 Note that this intrinsic cannot yet be called in a ``constexpr`` context.
 
+``__is_bitwise_cloneable``
+--
+
+A type trait is used to check whether a type can be safely copied by memcpy.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  bool __is_bitwise_cloneable(Type)
+
+**Description**:
+
+Objects of bitwise cloneable types can be bitwise copied by memcpy/memmove. The
+Clang compiler warrants that this behavior is well defined, and won't be
+broken by compiler optimizations and sanitizers.
+
+For implicit-lifetime types, the lifetime of the new object is implicitly
+started after the copy. For other types (e.g., classes with virtual methods),
+the lifetime isn't started, and using the object results in undefined behavior
+according to the C++ Standard.
+
+This builtin can be used in constant expressions.
+
 Atomic Min/Max builtins with memory ordering
 
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 39a9013c75a41..cc2ff9920b5c1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,9 @@ Non-comprehensive list of changes in this release
   ``-Winvalid-constexpr`` is not enabled for the function definition, which
   should result in mild compile-time performance improvements.
 
+- Added ``__buitlin_bitwise_clonable`` which is used to check whether a type
+  can be safely copied by memcpy/memmove.
+
 New Compiler Flags
 --
 - ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 263b632df23ce..4bb3a18102ebb 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1120,6 +1120,20 @@ class QualType {
   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
   bool isTriviallyCopyableType(const ASTContext ) const;
 
+  /// Return true if the type is safe to bitwise copy using memcpy/memmove.
+  ///
+  /// This is an extension in clang: bitwise clonable types act as trivially
+  /// copyable types, meaning their underlying bytes can be safely copied by
+  /// memcpy or memmove. After the copy, the destination object has the same
+  /// object representation.
+  ///
+  /// However, there are cases where it is not 

[clang] [Driver][test] Make the FileCheck less strict for some tests. (PR #94349)

2024-06-04 Thread Haojian Wu via cfe-commits

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


[clang] [Driver] Make the FileCheck less strict for some tests. (PR #94349)

2024-06-04 Thread Haojian Wu via cfe-commits


@@ -12,7 +12,7 @@
 // RUN: --sysroot=%S/Inputs/mips_mti_linux/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-BE-HF-32R2 %s
 //
-// CHECK-BE-HF-32R2: "{{[^"]*}}clang{{[^"]*}}" {{.*}} "-triple" 
"mips-mti-linux"

hokein wrote:

Thanks, I wasn't aware of the `-no-canonical-prefixes` option, it fixes the 
failures.

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


[clang] [Driver] Make the FileCheck less strict for some tests. (PR #94349)

2024-06-04 Thread Haojian Wu via cfe-commits

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

>From b9bd6c36196c7f1fdf6ec7a56260425e0b7255f7 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Tue, 4 Jun 2024 14:51:10 +0200
Subject: [PATCH] [Driver] Dont use absolute paths for invoking subcommands for
 driver tests

We see some tests are failing internally after 
12949c952c4fbad776a860c003ccf176973278a0.

In some CAS systems, we might not see the exact binary name (clang),
this patch adds the `-no-canonical-prefixes` option to the command line to not
realpath-ify the binary name.
---
 clang/test/Driver/mips-mti-linux.c |  4 ++--
 clang/test/Driver/openmp-offload-gpu.c |  6 +++---
 clang/test/Driver/openmp-offload.c | 14 +++---
 clang/test/Driver/ve-toolchain.c   |  2 +-
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/clang/test/Driver/mips-mti-linux.c 
b/clang/test/Driver/mips-mti-linux.c
index d10eb837b8a6e..e976269dfadf6 100644
--- a/clang/test/Driver/mips-mti-linux.c
+++ b/clang/test/Driver/mips-mti-linux.c
@@ -6,7 +6,7 @@
 //the --gcc-toolchain one.
 
 // = Big-endian, mips32r2, hard float
-// RUN: %clang -### %s 2>&1 \
+// RUN: %clang -### -no-canonical-prefixes %s 2>&1 \
 // RUN: --target=mips-mti-linux -mips32r2 -mhard-float -no-pie \
 // RUN: -rtlib=platform -fuse-ld=ld \
 // RUN: --sysroot=%S/Inputs/mips_mti_linux/sysroot \
@@ -25,7 +25,7 @@
 // CHECK-BE-HF-32R2-SAME: 
"[[SYSROOT]]/mips-r2-hard-musl/usr/lib{{/|}}crtn.o"
 
 // = Little-endian, mips32r2, hard float
-// RUN: %clang -### %s 2>&1 \
+// RUN: %clang -### -no-canonical-prefixes %s 2>&1 \
 // RUN: --target=mips-mti-linux -mips32r2 -EL -mhard-float -no-pie \
 // RUN: -rtlib=platform -fuse-ld=ld \
 // RUN: --sysroot=%S/Inputs/mips_mti_linux/sysroot \
diff --git a/clang/test/Driver/openmp-offload-gpu.c 
b/clang/test/Driver/openmp-offload-gpu.c
index 0b98aaf6ba53c..7c91bdab35be0 100644
--- a/clang/test/Driver/openmp-offload-gpu.c
+++ b/clang/test/Driver/openmp-offload-gpu.c
@@ -70,21 +70,21 @@
 
 /// Check that the runtime bitcode library is part of the compile line.
 /// Create a bogus bitcode library and specify it with 
libomptarget-nvptx-bc-path
-// RUN:   %clang -### -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda \
+// RUN:   %clang -### -no-canonical-prefixes -fopenmp=libomp 
-fopenmp-targets=nvptx64-nvidia-cuda \
 // RUN:   
--libomptarget-nvptx-bc-path=%S/Inputs/libomptarget/libomptarget-nvptx-test.bc \
 // RUN:   -Xopenmp-target -march=sm_52 
--cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \
 // RUN:   -fopenmp-relocatable-target -save-temps %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHK-BCLIB %s
 
 /// Specify the directory containing the bitcode lib, check clang picks the 
right one
-// RUN:   %clang -### -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda \
+// RUN:   %clang -### -no-canonical-prefixes -fopenmp=libomp 
-fopenmp-targets=nvptx64-nvidia-cuda \
 // RUN:   --libomptarget-nvptx-bc-path=%S/Inputs/libomptarget \
 // RUN:   -Xopenmp-target -march=sm_52 
--cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \
 // RUN:   -fopenmp-relocatable-target -save-temps \
 // RUN:   %s 2>&1 | FileCheck -check-prefix=CHK-BCLIB-DIR %s
 
 /// Create a bogus bitcode library and find it with LIBRARY_PATH
-// RUN:   env LIBRARY_PATH=%S/Inputs/libomptarget/subdir %clang -### 
-fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda \
+// RUN:   env LIBRARY_PATH=%S/Inputs/libomptarget/subdir %clang -### 
-no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda \
 // RUN:   -Xopenmp-target -march=sm_52 
--cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \
 // RUN:   -fopenmp-relocatable-target -save-temps \
 // RUN:   %s 2>&1 | FileCheck -check-prefix=CHK-ENV-BCLIB %s
diff --git a/clang/test/Driver/openmp-offload.c 
b/clang/test/Driver/openmp-offload.c
index 38065d9398f45..eaed0d66df75c 100644
--- a/clang/test/Driver/openmp-offload.c
+++ b/clang/test/Driver/openmp-offload.c
@@ -35,7 +35,7 @@
 /// ###
 
 /// Check -Xopenmp-target=powerpc64le-ibm-linux-gnu -mcpu=pwr7 is passed when 
compiling for the device.
-// RUN:   %clang -### -fopenmp=libomp 
-fopenmp-targets=powerpc64le-ibm-linux-gnu 
-Xopenmp-target=powerpc64le-ibm-linux-gnu -mcpu=pwr7 %s 2>&1 \
+// RUN:   %clang -### -no-canonical-prefixes -fopenmp=libomp 
-fopenmp-targets=powerpc64le-ibm-linux-gnu 
-Xopenmp-target=powerpc64le-ibm-linux-gnu -mcpu=pwr7 %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHK-FOPENMP-EQ-TARGET %s
 
 // CHK-FOPENMP-EQ-TARGET: clang{{.*}} "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
@@ -43,7 +43,7 @@
 /// ###
 
 /// Check -Xopenmp-target -mcpu=pwr7 is passed when compiling for the device.
-// RUN:   %clang -### -fopenmp=libomp 
-fopenmp-targets=powerpc64le-ibm-linux-gnu -Xopenmp-target -mcpu=pwr7 %s 2>&1 \
+// RUN:   %clang -### 

[clang] [Driver] Make the FileCheck less strict for some tests. (PR #94349)

2024-06-04 Thread Haojian Wu via cfe-commits

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

>From fa0880d477439e4af3f0b1b057dc1c66a2ccbc1e Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Tue, 4 Jun 2024 14:51:10 +0200
Subject: [PATCH] [Driver] Make the FileCheck less strict for some tests.

We see some tests are failing internally after 
12949c952c4fbad776a860c003ccf176973278a0.

In some CAS systems, we might not see the exact binary name (clang),
this patch removes the binary name in the FileCheck content to make
these tests work on CAS.
---
 clang/test/Driver/mips-mti-linux.c |  4 ++--
 clang/test/Driver/openmp-offload-gpu.c |  6 +++---
 clang/test/Driver/openmp-offload.c | 10 +-
 clang/test/Driver/ve-toolchain.c   |  2 +-
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/clang/test/Driver/mips-mti-linux.c 
b/clang/test/Driver/mips-mti-linux.c
index d10eb837b8a6e..0be25a284b777 100644
--- a/clang/test/Driver/mips-mti-linux.c
+++ b/clang/test/Driver/mips-mti-linux.c
@@ -12,7 +12,7 @@
 // RUN: --sysroot=%S/Inputs/mips_mti_linux/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-BE-HF-32R2 %s
 //
-// CHECK-BE-HF-32R2: "{{[^"]*}}clang{{[^"]*}}" {{.*}} "-triple" 
"mips-mti-linux"
+// CHECK-BE-HF-32R2: "-triple" "mips-mti-linux"
 // CHECK-BE-HF-32R2-SAME: "-target-cpu" "mips32r2"
 // CHECK-BE-HF-32R2-SAME: "-isysroot" "{{.*}}mips_mti_linux/sysroot"
 // CHECK-BE-HF-32R2: "{{[^"]*}}ld.lld{{[^"]*}}"
@@ -31,7 +31,7 @@
 // RUN: --sysroot=%S/Inputs/mips_mti_linux/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-LE-HF-32R2 %s
 //
-// CHECK-LE-HF-32R2: "{{[^"]*}}clang{{[^"]*}}" {{.*}} "-triple" 
"mipsel-mti-linux"
+// CHECK-LE-HF-32R2: "-triple" "mipsel-mti-linux"
 // CHECK-LE-HF-32R2-SAME: "-target-cpu" "mips32r2"
 // CHECK-LE-HF-32R2-SAME: "-isysroot" "{{.*}}mips_mti_linux/sysroot"
 // CHECK-LE-HF-32R2: "{{[^"]*}}ld.lld{{[^"]*}}"
diff --git a/clang/test/Driver/openmp-offload-gpu.c 
b/clang/test/Driver/openmp-offload-gpu.c
index 0b98aaf6ba53c..a9ddf65177ee5 100644
--- a/clang/test/Driver/openmp-offload-gpu.c
+++ b/clang/test/Driver/openmp-offload-gpu.c
@@ -89,9 +89,9 @@
 // RUN:   -fopenmp-relocatable-target -save-temps \
 // RUN:   %s 2>&1 | FileCheck -check-prefix=CHK-ENV-BCLIB %s
 
-// CHK-BCLIB: 
clang{{.*}}-triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}libomptarget-nvptx-test.bc
-// CHK-BCLIB-DIR: 
clang{{.*}}-triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}libomptarget{{/|}}libomptarget-nvptx-sm_52.bc
-// CHK-ENV-BCLIB: 
clang{{.*}}-triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}subdir{{/|}}libomptarget-nvptx-sm_52.bc
+// CHK-BCLIB: 
triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}libomptarget-nvptx-test.bc
+// CHK-BCLIB-DIR: 
triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}libomptarget{{/|}}libomptarget-nvptx-sm_52.bc
+// CHK-ENV-BCLIB: 
triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}subdir{{/|}}libomptarget-nvptx-sm_52.bc
 // CHK-BCLIB-NOT: {{error:|warning:}}
 
 /// ###
diff --git a/clang/test/Driver/openmp-offload.c 
b/clang/test/Driver/openmp-offload.c
index 38065d9398f45..9e7f523895ba3 100644
--- a/clang/test/Driver/openmp-offload.c
+++ b/clang/test/Driver/openmp-offload.c
@@ -38,7 +38,7 @@
 // RUN:   %clang -### -fopenmp=libomp 
-fopenmp-targets=powerpc64le-ibm-linux-gnu 
-Xopenmp-target=powerpc64le-ibm-linux-gnu -mcpu=pwr7 %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHK-FOPENMP-EQ-TARGET %s
 
-// CHK-FOPENMP-EQ-TARGET: clang{{.*}} "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
+// CHK-FOPENMP-EQ-TARGET: "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
 
 /// ###
 
@@ -46,7 +46,7 @@
 // RUN:   %clang -### -fopenmp=libomp 
-fopenmp-targets=powerpc64le-ibm-linux-gnu -Xopenmp-target -mcpu=pwr7 %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHK-FOPENMP-TARGET %s
 
-// CHK-FOPENMP-TARGET: clang{{.*}} "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
+// CHK-FOPENMP-TARGET: "-target-cpu" "pwr7" {{.*}}"-fopenmp-is-target-device"
 
 /// ##
 
@@ -54,7 +54,7 @@
 // RUN:%clang -### -fopenmp=libomp 
-fopenmp-targets=powerpc64le-ibm-linux-gnu --target=powerpc64le-ibm-linux-gnu 
-mcpu=pwr7 %s 2>&1 \
 // RUN:| FileCheck -check-prefix=CHK-FOPENMP-MCPU-TO-SAME-TRIPLE %s
 
-// CHK-FOPENMP-MCPU-TO-SAME-TRIPLE: clang{{.*}} "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
+// CHK-FOPENMP-MCPU-TO-SAME-TRIPLE: "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
 
 /// ##
 
@@ -62,7 +62,7 @@
 // RUN:not %clang -### -fopenmp=libomp 
-fopenmp-targets=nvptx64-nvidia-cuda --target=powerpc64le-ibm-linux-gnu 
-march=pwr7 %s 2>&1 \
 // 

[clang] [Driver] Make the FileCheck less strict for some tests. (PR #94349)

2024-06-04 Thread Haojian Wu via cfe-commits

https://github.com/hokein created 
https://github.com/llvm/llvm-project/pull/94349

We see some tests are failing internally after 
12949c952c4fbad776a860c003ccf176973278a0.

In CAS systems, we might not see the exact binary name (clang), this patch 
removes the binary name in the FileCheck content to make these tests work on 
CAS.

>From a5e8cfdc213a889e01080edb1cbdabe279c3449a Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Tue, 4 Jun 2024 14:51:10 +0200
Subject: [PATCH] [Driver] Make the FileCheck less strict for some tests.

We see some tests are failing internally after 
12949c952c4fbad776a860c003ccf176973278a0.

In some CAS systems, we might not see the exact binary name (clang),
this patch removes the binary name in the FileCheck content to make
these tests work on CAS.
---
 clang/test/Driver/mips-mti-linux.c |  4 ++--
 clang/test/Driver/openmp-offload-gpu.c |  6 +++---
 clang/test/Driver/openmp-offload.c | 10 +-
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/clang/test/Driver/mips-mti-linux.c 
b/clang/test/Driver/mips-mti-linux.c
index d10eb837b8a6e..0be25a284b777 100644
--- a/clang/test/Driver/mips-mti-linux.c
+++ b/clang/test/Driver/mips-mti-linux.c
@@ -12,7 +12,7 @@
 // RUN: --sysroot=%S/Inputs/mips_mti_linux/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-BE-HF-32R2 %s
 //
-// CHECK-BE-HF-32R2: "{{[^"]*}}clang{{[^"]*}}" {{.*}} "-triple" 
"mips-mti-linux"
+// CHECK-BE-HF-32R2: "-triple" "mips-mti-linux"
 // CHECK-BE-HF-32R2-SAME: "-target-cpu" "mips32r2"
 // CHECK-BE-HF-32R2-SAME: "-isysroot" "{{.*}}mips_mti_linux/sysroot"
 // CHECK-BE-HF-32R2: "{{[^"]*}}ld.lld{{[^"]*}}"
@@ -31,7 +31,7 @@
 // RUN: --sysroot=%S/Inputs/mips_mti_linux/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-LE-HF-32R2 %s
 //
-// CHECK-LE-HF-32R2: "{{[^"]*}}clang{{[^"]*}}" {{.*}} "-triple" 
"mipsel-mti-linux"
+// CHECK-LE-HF-32R2: "-triple" "mipsel-mti-linux"
 // CHECK-LE-HF-32R2-SAME: "-target-cpu" "mips32r2"
 // CHECK-LE-HF-32R2-SAME: "-isysroot" "{{.*}}mips_mti_linux/sysroot"
 // CHECK-LE-HF-32R2: "{{[^"]*}}ld.lld{{[^"]*}}"
diff --git a/clang/test/Driver/openmp-offload-gpu.c 
b/clang/test/Driver/openmp-offload-gpu.c
index 0b98aaf6ba53c..a9ddf65177ee5 100644
--- a/clang/test/Driver/openmp-offload-gpu.c
+++ b/clang/test/Driver/openmp-offload-gpu.c
@@ -89,9 +89,9 @@
 // RUN:   -fopenmp-relocatable-target -save-temps \
 // RUN:   %s 2>&1 | FileCheck -check-prefix=CHK-ENV-BCLIB %s
 
-// CHK-BCLIB: 
clang{{.*}}-triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}libomptarget-nvptx-test.bc
-// CHK-BCLIB-DIR: 
clang{{.*}}-triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}libomptarget{{/|}}libomptarget-nvptx-sm_52.bc
-// CHK-ENV-BCLIB: 
clang{{.*}}-triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}subdir{{/|}}libomptarget-nvptx-sm_52.bc
+// CHK-BCLIB: 
triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}libomptarget-nvptx-test.bc
+// CHK-BCLIB-DIR: 
triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}libomptarget{{/|}}libomptarget-nvptx-sm_52.bc
+// CHK-ENV-BCLIB: 
triple{{.*}}nvptx64-nvidia-cuda{{.*}}-mlink-builtin-bitcode{{.*}}subdir{{/|}}libomptarget-nvptx-sm_52.bc
 // CHK-BCLIB-NOT: {{error:|warning:}}
 
 /// ###
diff --git a/clang/test/Driver/openmp-offload.c 
b/clang/test/Driver/openmp-offload.c
index 38065d9398f45..9e7f523895ba3 100644
--- a/clang/test/Driver/openmp-offload.c
+++ b/clang/test/Driver/openmp-offload.c
@@ -38,7 +38,7 @@
 // RUN:   %clang -### -fopenmp=libomp 
-fopenmp-targets=powerpc64le-ibm-linux-gnu 
-Xopenmp-target=powerpc64le-ibm-linux-gnu -mcpu=pwr7 %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHK-FOPENMP-EQ-TARGET %s
 
-// CHK-FOPENMP-EQ-TARGET: clang{{.*}} "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
+// CHK-FOPENMP-EQ-TARGET: "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
 
 /// ###
 
@@ -46,7 +46,7 @@
 // RUN:   %clang -### -fopenmp=libomp 
-fopenmp-targets=powerpc64le-ibm-linux-gnu -Xopenmp-target -mcpu=pwr7 %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHK-FOPENMP-TARGET %s
 
-// CHK-FOPENMP-TARGET: clang{{.*}} "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
+// CHK-FOPENMP-TARGET: "-target-cpu" "pwr7" {{.*}}"-fopenmp-is-target-device"
 
 /// ##
 
@@ -54,7 +54,7 @@
 // RUN:%clang -### -fopenmp=libomp 
-fopenmp-targets=powerpc64le-ibm-linux-gnu --target=powerpc64le-ibm-linux-gnu 
-mcpu=pwr7 %s 2>&1 \
 // RUN:| FileCheck -check-prefix=CHK-FOPENMP-MCPU-TO-SAME-TRIPLE %s
 
-// CHK-FOPENMP-MCPU-TO-SAME-TRIPLE: clang{{.*}} "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
+// CHK-FOPENMP-MCPU-TO-SAME-TRIPLE: "-target-cpu" "pwr7" 
{{.*}}"-fopenmp-is-target-device"
 
 /// 

[clang] [clang] NFCI: remove obsolete workaround for template default arguments (PR #94311)

2024-06-04 Thread Haojian Wu via cfe-commits

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

Thanks for the cleanup, this looks good to me.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-29 Thread Haojian Wu via cfe-commits

hokein wrote:

Add @eugenis as a reviewer, could you take a look on the sanitizer bit? 

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-29 Thread Haojian Wu via cfe-commits

hokein wrote:

> Could we rewrite the description and documentation to capture what the type 
> trait is doing now? We have a lot of references to the 
> `is_trivially_copyable`, which is almost fully irrelevant to the current 
> implementation.

Thanks, I updated the PR description and documentation in the code, please take 
a look again.
I think it is worth to mentioning the `is_trivially_copyable`, they're 
conceptually relevant (users use `is_trivially_copyable` as a safe guard for 
`memcpy`).

> Also, is there a _simple_ way to make this work with the corresponding 
> sanitizer? If not or it requires too much work, we could definitely return 
> false here. Just making sure we explored this.

This doesn't scale well. There are a few sanitizers (asan, msan etc), and each 
sanitizer has their own version of memcpy. It is non-trivial to check all 
sanitizers to ensure all of them work properly. And it doesn't solve types with 
non-trivial  ObjectiveC lifetime.
 



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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-29 Thread Haojian Wu via cfe-commits


@@ -4016,6 +4016,34 @@ Note that the `size` argument must be a compile time 
constant.
 
 Note that this intrinsic cannot yet be called in a ``constexpr`` context.
 
+``__is_bitwise_cloneable``
+--
+
+A type trait is used to check whether a type can be safely copied by memcpy.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  bool __is_bitwise_cloneable(Type)
+
+**Description**:
+
+This trait is similar to `std::is_trivially_copyable`, but additionally allows
+to have user-defined constructors, virtual functions and virtual bases. It is 
up
+to the user code to guarantee that a bitwise copy results in non-broken object
+and that the lifetime of an object is properly started.
+
+Objects of bitwise cloneable types can be bitwise copied by memcpy/memmove. The
+Clang compiler warrants that this behavior is well defined, and won't be
+broken by compiler optimizations.
+
+After the copy, the lifetime of the new object isn't started yet (unless the
+type is trivially copyable). Users must ensure its lifetime is started to avoid
+undefined behavior.

hokein wrote:

> What should the intended action taken by the user be? Is this advice 
> actionable?
I guess that if the type is implicit-lifetime-type, users could use 
start_lifetime_as (although it's not implemented in Clang).
AFAIK, there is no way to start a lifetime of other objects (e.g. containing 
virtual members).

For implicit-lifetime types, users don't need to start the lifetime explicitly, 
the `memcpy` implicitly starts the lifetime of the object, per the 
[standard](https://eel.is/c++draft/intro.object#note-6); for other types, yeah, 
this is no standard way to do it (for our case, we plan to do the trick with 
`__builtin_launder`, but I would not mention it in the public doc).

How about this?

```
For implicit-lifetime types, the lifetime of the new object is implicitly 
started after the memcpy. For other types (e.g., classes with virtual methods), 
the lifetime isn't started, and using the object results in undefined behavior 
according to the C++ Standard, and there is no standard way to start the 
lifetime.
```

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-29 Thread Haojian Wu via cfe-commits


@@ -2749,6 +2749,17 @@ bool QualType::isTriviallyCopyableType(const ASTContext 
) const {
  /*IsCopyConstructible=*/false);
 }
 
+bool QualType::isBitwiseCloneableType(const ASTContext & Context) const {
+  if (const auto *RD = getCanonicalType()->getAsCXXRecordDecl()) {

hokein wrote:

Agree, for the safety reason, we should disable it for NonTrivialObjCLifetime. 
Done.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-29 Thread Haojian Wu via cfe-commits


@@ -1120,6 +1120,14 @@ class QualType {
   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
   bool isTriviallyCopyableType(const ASTContext ) const;
 
+  /// Return true if the type is safe to bitwise copy by memcpy.
+  ///
+  /// This is an extension in clang: bitwise clonable types act as trivially

hokein wrote:

Done, updated the documentation accordingly, please take a second look.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-29 Thread Haojian Wu via cfe-commits

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

>From 011d6bbb434bdb46efe92891fe356885f82c4445 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 25 Mar 2024 15:10:51 +0100
Subject: [PATCH] ination of 2 commits.

[clang] Implement a bitwise_copyable builtin type trait.

This patch implements a `__is_bitwise_copyable` builtin in clang.

The bitwise copyable types act as the trivially copyable types, but
they support a wider range of types (e.g. classes with virtual methods) --
their underlying types can be safely copied by `memcopy` or `memmove`,
the clang compiler guarantees that both source and destination objects
have the same *object* representations after the copy operation, and the
lifetime of the destination object implicitly starts.

A particular use case of this builtin is to clone an object via memcopy
(without running the constructor):

```
Message* clone(const Message* src, char* buffer, int size) {
  if constexpr __is_bitwise_copyable(Message) {
// bitwise copy to buffer
__builtin_memcpy(buffer, src, size);
// using __builtin_launder to prevent miscompile for 
-fstrict-vtable-pointers.
return __builtin_launder(reinterpret_cast(buffer));
  }
  // Fallback the operator new, which calls the constructor to start the 
lifetime.
  return new(buffer) Message(src);
}
```

Note that the definition of bitwise copyable is not tied to the Rule Of
Five, so users of this builtin must guarantee that program semantic constraints
are satisfied, e.g. no double resource deallocations.

Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy
---
 clang/docs/LanguageExtensions.rst | 28 +++
 clang/docs/ReleaseNotes.rst   |  3 ++
 clang/include/clang/AST/Type.h| 16 +
 clang/include/clang/Basic/TokenKinds.def  |  2 ++
 clang/lib/AST/Type.cpp| 35 +++
 clang/lib/Sema/SemaExprCXX.cpp|  3 ++
 ...builtin-is-bitwise-cloneable-fsanitize.cpp | 34 ++
 .../SemaCXX/builtin-is-bitwise-cloneable.cpp  |  9 +
 clang/test/SemaObjCXX/arc-type-traits.mm  |  9 +
 9 files changed, 139 insertions(+)
 create mode 100644 
clang/test/SemaCXX/builtin-is-bitwise-cloneable-fsanitize.cpp
 create mode 100644 clang/test/SemaCXX/builtin-is-bitwise-cloneable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 46f99d0bbdd06..da569b9577e75 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -4016,6 +4016,34 @@ Note that the `size` argument must be a compile time 
constant.
 
 Note that this intrinsic cannot yet be called in a ``constexpr`` context.
 
+``__is_bitwise_cloneable``
+--
+
+A type trait is used to check whether a type can be safely copied by memcpy.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  bool __is_bitwise_cloneable(Type)
+
+**Description**:
+
+This trait is similar to `std::is_trivially_copyable`, but additionally allows
+to have user-defined constructors, virtual functions and virtual bases. It is 
up
+to the user code to guarantee that a bitwise copy results in non-broken object.
+
+Objects of bitwise cloneable types can be bitwise copied by memcpy/memmove. The
+Clang compiler warrants that this behavior is well defined, and won't be
+broken by compiler optimizations.
+
+For implicit-lifetime types, the lifetime of the new object is implicitly
+started after the copy. For other types (e.g., classes with virtual methods),
+the lifetime isn't started, and using the object results in undefined behavior
+according to the C++ Standard.
+
+This builtin can be used in constant expressions.
+
 Atomic Min/Max builtins with memory ordering
 
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 58e407a724a9c..2143611560278 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -318,6 +318,9 @@ Non-comprehensive list of changes in this release
 - Builtins ``__builtin_shufflevector()`` and ``__builtin_convertvector()`` may
   now be used within constant expressions.
 
+- Added ``__buitlin_bitwise_clonable`` which is used to check whether a type
+  can be safely copied by memcpy/memmove.
+
 New Compiler Flags
 --
 - ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 263b632df23ce..0adada068bbfe 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1120,6 +1120,22 @@ class QualType {
   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
   bool isTriviallyCopyableType(const ASTContext ) const;
 
+  /// Return true if the type is safe to bitwise copy using memcpy/memmove.
+  ///
+  /// This is an extension in clang: bitwise clonable types act as 

[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-29 Thread Haojian Wu via cfe-commits

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-28 Thread Haojian Wu via cfe-commits

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

>From 49747cde60dc8a1f4ed4ddcee020f71c88f35287 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 25 Mar 2024 15:10:51 +0100
Subject: [PATCH] [clang] Implement a bitwise_copyable builtin type trait.

This patch implements a `__is_bitwise_copyable` builtin in clang.

The bitwise copyable types act as the trivially copyable types, but
they support a wider range of types (e.g. classes with virtual methods) --
their underlying types can be safely copied by `memcopy` or `memmove`,
the clang compiler guarantees that both source and destination objects
have the same *object* representations after the copy operation, and the
lifetime of the destination object implicitly starts.

A particular use case of this builtin is to clone an object via memcopy
(without running the constructor):

```
Message* clone(const Message* src, char* buffer, int size) {
  if constexpr __is_bitwise_copyable(Message) {
// bitwise copy to buffer
__builtin_memcpy(buffer, src, size);
// using __builtin_launder to prevent miscompile for 
-fstrict-vtable-pointers.
return __builtin_launder(reinterpret_cast(buffer));
  }
  // Fallback the operator new, which calls the constructor to start the 
lifetime.
  return new(buffer) Message(src);
}
```

Note that the definition of bitwise copyable is not tied to the Rule Of
Five, so users of this builtin must guarantee that program semantic constraints
are satisfied, e.g. no double resource deallocations.

Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy
---
 clang/docs/LanguageExtensions.rst | 28 +++
 clang/include/clang/AST/Type.h|  8 ++
 clang/include/clang/Basic/TokenKinds.def  |  2 ++
 clang/lib/AST/Type.cpp| 11 
 clang/lib/Sema/SemaExprCXX.cpp|  3 ++
 ...builtin-is-bitwise-cloneable-fsanitize.cpp | 20 +
 .../SemaCXX/builtin-is-bitwise-cloneable.cpp  |  6 
 7 files changed, 78 insertions(+)
 create mode 100644 
clang/test/SemaCXX/builtin-is-bitwise-cloneable-fsanitize.cpp
 create mode 100644 clang/test/SemaCXX/builtin-is-bitwise-cloneable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 46f99d0bbdd06..0168411d04f50 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -4016,6 +4016,34 @@ Note that the `size` argument must be a compile time 
constant.
 
 Note that this intrinsic cannot yet be called in a ``constexpr`` context.
 
+``__is_bitwise_cloneable``
+--
+
+A type trait is used to check whether a type can be safely copied by memcpy.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  bool __is_bitwise_cloneable(Type)
+
+**Description**:
+
+This trait is similar to `std::is_trivially_copyable`, but additionally allows
+to have user-defined constructors, virtual functions and virtual bases. It is 
up
+to the user code to guarantee that a bitwise copy results in non-broken object
+and that the lifetime of an object is properly started.
+
+Objects of bitwise cloneable types can be bitwise copied by memcpy/memmove. The
+Clang compiler warrants that this behavior is well defined, and won't be
+broken by compiler optimizations.
+
+After the copy, the lifetime of the new object isn't started yet (unless the
+type is trivially copyable). Users must ensure its lifetime is started to avoid
+undefined behavior.
+
+This builtin can be used in constant expressions.
+
 Atomic Min/Max builtins with memory ordering
 
 
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 263b632df23ce..d79b942c599cf 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1120,6 +1120,14 @@ class QualType {
   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
   bool isTriviallyCopyableType(const ASTContext ) const;
 
+  /// Return true if the type is safe to bitwise copy by memcpy.
+  ///
+  /// This is an extension in clang: bitwise clonable types act as trivially
+  /// copyable types, their underlying bytes can be safely copied by memcpy or
+  /// memmove. Clang guarantees that the destination has the same **object**
+  /// representations after the copy.
+  bool isBitwiseCloneableType(const ASTContext ) const;
+
   /// Return true if this is a trivially copyable type
   bool isTriviallyCopyConstructibleType(const ASTContext ) const;
 
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index b5a0e9df9f7ae..9c4b17465e18a 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -542,6 +542,8 @@ TYPE_TRAIT_2(__reference_converts_from_temporary, 
ReferenceConvertsFromTemporary
 // is not exposed to users.
 TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)
 

[clang] [clang] CTAD alias: fix transformation for require-clause expr Part2. (PR #93533)

2024-05-28 Thread Haojian Wu via cfe-commits

https://github.com/hokein created 
https://github.com/llvm/llvm-project/pull/93533

In the https://github.com/llvm/llvm-project/pull/90961 fix, we miss a case 
where the undeduced template parameters of the underlying deduction guide are 
not transformed, which leaves incorrect depth/index information, and causes 
crashes when evaluating constraints.

This patch fix this missing case.

Fixes #92596
Fixes #92212

>From efd657d537e57fd791dcd9cf0c38cc578c023e00 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 17 May 2024 15:28:48 +0200
Subject: [PATCH] [clang] CTAD alias: fix transformation for require-clause
 expr Part2.

In the https://github.com/llvm/llvm-project/pull/90961 fix, we miss a
case where the undeduced template parameters of the underlying deduction
guide is not transformed, which leaves incorrect depth/index
information, and causes crash when evaluating the constraints.

This patch fix this missing case.

Fixes #92596
Fixes #92212
---
 clang/lib/Sema/SemaTemplate.cpp  | 32 
 clang/test/AST/ast-dump-ctad-alias.cpp   | 25 +++
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 25 +++
 3 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 39e9dbed0c3e0..62d7097f68785 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2780,6 +2780,7 @@ Expr *
 buildAssociatedConstraints(Sema , FunctionTemplateDecl *F,
TypeAliasTemplateDecl *AliasTemplate,
ArrayRef DeduceResults,
+   unsigned UndeducedTemplateParameterStartIndex,
Expr *IsDeducible) {
   Expr *RC = F->getTemplateParameters()->getRequiresClause();
   if (!RC)
@@ -2840,8 +2841,22 @@ buildAssociatedConstraints(Sema , 
FunctionTemplateDecl *F,
 
   for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
 const auto  = DeduceResults[Index];
-if (D.isNull())
+if (D.isNull()) { // non-deduced template parameters of f
+  auto TP = F->getTemplateParameters()->getParam(Index);
+  MultiLevelTemplateArgumentList Args;
+  Args.setKind(TemplateSubstitutionKind::Rewrite);
+  Args.addOuterTemplateArguments(TemplateArgsForBuildingRC);
+  // Rebuild the template parameter with updated depth and index.
+  NamedDecl *NewParam = transformTemplateParameter(
+  SemaRef, F->getDeclContext(), TP, Args,
+  /*NewIndex=*/UndeducedTemplateParameterStartIndex++,
+  getTemplateParameterDepth(TP) + AdjustDepth);
+
+  assert(TemplateArgsForBuildingRC[Index].isNull());
+  TemplateArgsForBuildingRC[Index] = Context.getCanonicalTemplateArgument(
+  Context.getInjectedTemplateArg(NewParam));
   continue;
+}
 TemplateArgumentLoc Input =
 SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{});
 TemplateArgumentLoc Output;
@@ -2857,9 +2872,11 @@ buildAssociatedConstraints(Sema , 
FunctionTemplateDecl *F,
   MultiLevelTemplateArgumentList ArgsForBuildingRC;
   ArgsForBuildingRC.setKind(clang::TemplateSubstitutionKind::Rewrite);
   ArgsForBuildingRC.addOuterTemplateArguments(TemplateArgsForBuildingRC);
-  // For 2), if the underlying F is instantiated from a member template, we 
need
-  // the entire template argument list, as the constraint AST in the
-  // require-clause of F remains completely uninstantiated.
+  // For 2), if the underlying function template F is nested in a class 
template
+  // (either instantiated from an explicitly-written deduction guide, or
+  // synthesized from a constructor), we need the entire template argument 
list,
+  // as the constraint AST in the require-clause of F remains completely
+  // uninstantiated.
   //
   // For example:
   //   template  // depth 0
@@ -2882,7 +2899,8 @@ buildAssociatedConstraints(Sema , 
FunctionTemplateDecl *F,
   // We add the outer template arguments which is [int] to the multi-level arg
   // list to ensure that the occurrence U in `C` will be replaced with int
   // during the substitution.
-  if (F->getInstantiatedFromMemberTemplate()) {
+  if (F->getLexicalDeclContext()->getDeclKind() ==
+  clang::Decl::ClassTemplateSpecialization) {
 auto OuterLevelArgs = SemaRef.getTemplateInstantiationArgs(
 F, F->getLexicalDeclContext(),
 /*Final=*/false, /*Innermost=*/std::nullopt,
@@ -3100,6 +3118,7 @@ BuildDeductionGuideForTypeAlias(Sema ,
 Context.getInjectedTemplateArg(NewParam));
 TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;
   }
+  unsigned UndeducedTemplateParameterStartIndex = FPrimeTemplateParams.size();
   //   ...followed by the template parameters of f that were not deduced
   //   (including their default template arguments)
   for (unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {
@@ -3169,7 +3188,8 @@ 

[clang] [Sema] Fix an out-of-bounds crash when diagnosing bad conversion for a function with a parameter pack. (PR #92721)

2024-05-27 Thread Haojian Wu via cfe-commits

hokein wrote:

The crash is already fixed by 
https://github.com/llvm/llvm-project/commit/7a28a5b3fee6c78ad59af79a3d03c00db153c49f

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


[clang] [Sema] Fix an out-of-bounds crash when diagnosing bad conversion for a function with a parameter pack. (PR #92721)

2024-05-27 Thread Haojian Wu via cfe-commits

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


[clang] [Sema] Fix an out-of-bounds crash when diagnosing bad conversion for a function with a parameter pack. (PR #92721)

2024-05-27 Thread Haojian Wu via cfe-commits


@@ -11298,8 +11298,14 @@ static void DiagnoseBadConversion(Sema , 
OverloadCandidate *Cand,
   Expr *FromExpr = Conv.Bad.FromExpr;
   QualType FromTy = Conv.Bad.getFromType();
   QualType ToTy = Conv.Bad.getToType();
-  SourceRange ToParamRange =
-  !isObjectArgument ? Fn->getParamDecl(I)->getSourceRange() : 
SourceRange();
+  SourceRange ToParamRange;
+  if (!isObjectArgument) {
+if (I < Fn->getNumParams())
+  ToParamRange = Fn->getParamDecl(I)->getSourceRange();
+else
+  // parameter pack case.
+  ToParamRange = Fn->parameters().back()->getSourceRange();

hokein wrote:

thanks for the test cases. (I wonder if there is a case where we should point 
at the second pack, but I don't come up with one, I think using the first pack 
is probably good enough. Alternatively, we could use the full 
`getParametersSourceRange` range without finding a particular pack, but it 
provides less precise location information).

> Should we put that in a function in FunctionDecl?

Probably not worth, it seems heavy to add a method in FunctionDecl to only fix 
this regression.

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


[clang] [Sema] Fix an out-of-bounds crash when diagnosing bad conversion for a function with a parameter pack. (PR #92721)

2024-05-27 Thread Haojian Wu via cfe-commits


@@ -11298,8 +11298,14 @@ static void DiagnoseBadConversion(Sema , 
OverloadCandidate *Cand,
   Expr *FromExpr = Conv.Bad.FromExpr;
   QualType FromTy = Conv.Bad.getFromType();
   QualType ToTy = Conv.Bad.getToType();
-  SourceRange ToParamRange =
-  !isObjectArgument ? Fn->getParamDecl(I)->getSourceRange() : 
SourceRange();
+  SourceRange ToParamRange;
+  if (!isObjectArgument) {
+if (I < Fn->getNumParams())
+  ToParamRange = Fn->getParamDecl(I)->getSourceRange();
+else
+  // parameter pack case.

hokein wrote:

Done. 

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


[clang] [Sema] Fix an out-of-bounds crash when diagnosing bad conversion for a function with a parameter pack. (PR #92721)

2024-05-27 Thread Haojian Wu via cfe-commits

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

>From e2dc2cecee5891b88ff4c2e473220cc9fd36df34 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Sun, 19 May 2024 22:47:14 +0200
Subject: [PATCH 1/2] [Sema] Fix an out-of-bounds crash when diagnosing bad
 conversion for a function with a parameter pack.

---
 clang/docs/ReleaseNotes.rst   |  2 ++
 clang/lib/Sema/SemaOverload.cpp   | 10 --
 clang/test/Misc/diag-overload-cand-ranges.cpp |  8 
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 825e91876ffce..9fd8661949113 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -629,6 +629,8 @@ Bug Fixes in This Version
 - ``__is_array`` and ``__is_bounded_array`` no longer return ``true`` for
   zero-sized arrays. Fixes (#GH54705).
 
+- Fix an out-of-bounds crash when diagnosing bad conversion for a function 
with a parameter pack. 
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 0c89fca8d38eb..a9603e63336ac 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11301,8 +11301,14 @@ static void DiagnoseBadConversion(Sema , 
OverloadCandidate *Cand,
   Expr *FromExpr = Conv.Bad.FromExpr;
   QualType FromTy = Conv.Bad.getFromType();
   QualType ToTy = Conv.Bad.getToType();
-  SourceRange ToParamRange =
-  !isObjectArgument ? Fn->getParamDecl(I)->getSourceRange() : 
SourceRange();
+  SourceRange ToParamRange;
+  if (!isObjectArgument) {
+if (I < Fn->getNumParams())
+  ToParamRange = Fn->getParamDecl(I)->getSourceRange();
+else
+  // parameter pack case.
+  ToParamRange = Fn->parameters().back()->getSourceRange();
+  }
 
   if (FromTy == S.Context.OverloadTy) {
 assert(FromExpr && "overload set argument came from implicit argument?");
diff --git a/clang/test/Misc/diag-overload-cand-ranges.cpp 
b/clang/test/Misc/diag-overload-cand-ranges.cpp
index 080ca484d4b74..06d638d9b719c 100644
--- a/clang/test/Misc/diag-overload-cand-ranges.cpp
+++ b/clang/test/Misc/diag-overload-cand-ranges.cpp
@@ -70,3 +70,11 @@ template  class Type1 {};
 template  void Function1(int zz, Type1 , int ww) {}
 
 void Function() { Function1(33, Type1<-42>(), 66); }
+
+// CHECK:  error: no matching function for call to 'b'
+// CHECK:  :{[[@LINE+1]]:41-[[@LINE+1]]:45}: note: {{.*}} no known 
conversion from 'int' to 'ForwardClass' for 3rd argument
+template  void b(T, U...);
+class ForwardClass;
+void NoCrash() {
+  b(1, 1, 0);
+}

>From 4358b43e283cb13dbe4d32fcce3c68b6da15b12a Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 27 May 2024 09:58:04 +0200
Subject: [PATCH 2/2] review comments

Diagnose on the first parameter pack.
---
 clang/lib/Sema/SemaOverload.cpp   | 12 +---
 clang/test/Misc/diag-overload-cand-ranges.cpp |  6 +-
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index a9603e63336ac..f9a5032e10c2d 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11305,9 +11305,15 @@ static void DiagnoseBadConversion(Sema , 
OverloadCandidate *Cand,
   if (!isObjectArgument) {
 if (I < Fn->getNumParams())
   ToParamRange = Fn->getParamDecl(I)->getSourceRange();
-else
-  // parameter pack case.
-  ToParamRange = Fn->parameters().back()->getSourceRange();
+else {
+  // For the parameter pack case, diagnose on the first pack.
+  for (const auto* ParamDecl : Fn->parameters()) {
+if (ParamDecl->isParameterPack()) {
+  ToParamRange = ParamDecl->getSourceRange();
+  break;
+}
+  }
+}
   }
 
   if (FromTy == S.Context.OverloadTy) {
diff --git a/clang/test/Misc/diag-overload-cand-ranges.cpp 
b/clang/test/Misc/diag-overload-cand-ranges.cpp
index 06d638d9b719c..a70ba0d1b1f77 100644
--- a/clang/test/Misc/diag-overload-cand-ranges.cpp
+++ b/clang/test/Misc/diag-overload-cand-ranges.cpp
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info %s 
2>&1 | FileCheck %s --strict-whitespace
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info 
-std=c++20 %s 2>&1 | FileCheck %s --strict-whitespace
 // CHECK:  error: no matching function
 template  struct mcdata {
   typedef int result_type;
@@ -74,7 +74,11 @@ void Function() { Function1(33, Type1<-42>(), 66); }
 // CHECK:  error: no matching function for call to 'b'
 // CHECK:  :{[[@LINE+1]]:41-[[@LINE+1]]:45}: note: {{.*}} no known 
conversion from 'int' to 'ForwardClass' for 3rd argument
 template  void b(T, U...);
+// CHECK:  error: no matching function for call to 'abbreviated_func'
+// CHECK:  :{[[@LINE+1]]:23-[[@LINE+1]]:30}: note: {{.*}} no known 
conversion from 'int' to 

[clang] [Sema] Fix an out-of-bounds crash when diagnosing bad conversion for a function with a parameter pack. (PR #92721)

2024-05-27 Thread Haojian Wu via cfe-commits

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


[clang] [clang] CTAD alias: Fix missing template arg packs during the transformation (PR #92535)

2024-05-20 Thread Haojian Wu via cfe-commits

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


[clang] [Sema] Fix an out-of-bounds crash when diagnosing bad conversion for a function with a parameter pack. (PR #92721)

2024-05-20 Thread Haojian Wu via cfe-commits

https://github.com/hokein created 
https://github.com/llvm/llvm-project/pull/92721

None

>From 2aa2caf15282d28e9fda99d51776d842d3d57e95 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Sun, 19 May 2024 22:47:14 +0200
Subject: [PATCH] [Sema] Fix an out-of-bounds crash when diagnosing bad
 conversion for a function with a parameter pack.

---
 clang/docs/ReleaseNotes.rst   |  2 ++
 clang/lib/Sema/SemaOverload.cpp   | 10 --
 clang/test/Misc/diag-overload-cand-ranges.cpp |  8 
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index be4cded276321..de3d258ae578a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -573,6 +573,8 @@ Bug Fixes in This Version
 - Clang now correctly disallows VLA type compound literals, e.g. 
``(int[size]){}``,
   as the C standard mandates. (#GH89835)
 
+- Fix an out-of-bounds crash when diagnosing bad conversion for a function 
with a parameter pack. 
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 2eb25237a0de6..73a175f724402 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11298,8 +11298,14 @@ static void DiagnoseBadConversion(Sema , 
OverloadCandidate *Cand,
   Expr *FromExpr = Conv.Bad.FromExpr;
   QualType FromTy = Conv.Bad.getFromType();
   QualType ToTy = Conv.Bad.getToType();
-  SourceRange ToParamRange =
-  !isObjectArgument ? Fn->getParamDecl(I)->getSourceRange() : 
SourceRange();
+  SourceRange ToParamRange;
+  if (!isObjectArgument) {
+if (I < Fn->getNumParams())
+  ToParamRange = Fn->getParamDecl(I)->getSourceRange();
+else
+  // parameter pack case.
+  ToParamRange = Fn->parameters().back()->getSourceRange();
+  }
 
   if (FromTy == S.Context.OverloadTy) {
 assert(FromExpr && "overload set argument came from implicit argument?");
diff --git a/clang/test/Misc/diag-overload-cand-ranges.cpp 
b/clang/test/Misc/diag-overload-cand-ranges.cpp
index 080ca484d4b74..06d638d9b719c 100644
--- a/clang/test/Misc/diag-overload-cand-ranges.cpp
+++ b/clang/test/Misc/diag-overload-cand-ranges.cpp
@@ -70,3 +70,11 @@ template  class Type1 {};
 template  void Function1(int zz, Type1 , int ww) {}
 
 void Function() { Function1(33, Type1<-42>(), 66); }
+
+// CHECK:  error: no matching function for call to 'b'
+// CHECK:  :{[[@LINE+1]]:41-[[@LINE+1]]:45}: note: {{.*}} no known 
conversion from 'int' to 'ForwardClass' for 3rd argument
+template  void b(T, U...);
+class ForwardClass;
+void NoCrash() {
+  b(1, 1, 0);
+}

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


[clang] [clang][AST] Fix end location of DeclarationNameInfo on instantiated methods (PR #92654)

2024-05-20 Thread Haojian Wu via cfe-commits

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

nit: add a note in `clang/docs/ReleaseNotes.rst` 

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


[clang] [clang] CTAD alias: Fix missing template arg packs during the transformation (PR #92535)

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

https://github.com/hokein created 
https://github.com/llvm/llvm-project/pull/92535

clang rejects some valid code (see testcases) because of an incorrect 
transformed deduction guides. This patch fixes it.

We miss the template argument packs during the transformation (`auto 
(type-parameter-0-0...) -> Foo<>`). In 
`TreeTransform::TransformTemplateArguments `, we have a logic of handling 
template argument packs which were originally added to support CTAD alias, it 
doesn't seem to be needed, we need to unpack them. 

>From 21ff4048fdee4f76d7d73ae9f2bfaf18614a4a3b Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 17 May 2024 14:12:04 +0200
Subject: [PATCH] [clang] CTAD alias: Fix missing template arg packs during the
 transformation.

---
 clang/lib/Sema/TreeTransform.h   |  8 
 clang/test/AST/ast-dump-ctad-alias.cpp   | 20 
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp |  5 +
 3 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index b10e5ba65eb1c..f9fec21bf5bb6 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4818,14 +4818,6 @@ bool TreeTransform::TransformTemplateArguments(
 TemplateArgumentLoc In = *First;
 
 if (In.getArgument().getKind() == TemplateArgument::Pack) {
-  // When building the deduction guides, we rewrite the argument packs
-  // instead of unpacking.
-  if (getSema().CodeSynthesisContexts.back().Kind ==
-  Sema::CodeSynthesisContext::BuildingDeductionGuides) {
-if (getDerived().TransformTemplateArgument(In, Out, Uneval))
-  return true;
-continue;
-  }
   // Unpack argument packs, which we translate them into separate
   // arguments.
   // FIXME: We could do much better if we could guarantee that the
diff --git a/clang/test/AST/ast-dump-ctad-alias.cpp 
b/clang/test/AST/ast-dump-ctad-alias.cpp
index 7fe6c05621eee..9382558393e4c 100644
--- a/clang/test/AST/ast-dump-ctad-alias.cpp
+++ b/clang/test/AST/ast-dump-ctad-alias.cpp
@@ -48,3 +48,23 @@ Out2::AInner t(1.0);
 // CHECK-NEXT: |   |-TemplateArgument type 'double'
 // CHECK-NEXT: |   | `-BuiltinType {{.*}} 'double'
 // CHECK-NEXT: |   `-ParmVarDecl {{.*}} 'double'
+
+template 
+struct Foo {
+  Foo(T1...);
+};
+
+template 
+using AFoo = Foo;
+AFoo a(1, 2);
+// CHECK:  |-CXXDeductionGuideDecl {{.*}} implicit  'auto (type-parameter-0-0...) -> Foo'
+// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'type-parameter-0-0...' pack
+// CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} implicit used  'auto (int, int) -> Foo' implicit_instantiation
+
+template 
+using BFoo = Foo;
+BFoo b2(1.0, 2.0);
+// CHECK:  |-CXXDeductionGuideDecl {{.*}} implicit  'auto (type-parameter-0-0, type-parameter-0-0) -> Foo'
+// CHECK-NEXT: | | |-ParmVarDecl {{.*}} 'type-parameter-0-0'
+// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'type-parameter-0-0'
+// CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} implicit used  'auto (double, double) -> Foo' implicit_instantiation
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp 
b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 7c186dc379c7b..479b0e3606721 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -173,6 +173,11 @@ template 
 using AFoo = Foo;
 
 auto b = AFoo{};
+AFoo a(1, 2);
+
+template 
+using BFoo = Foo;
+BFoo b2(1.0, 2.0);
 } // namespace test13
 
 namespace test14 {

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

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


@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+// Scalar types are bitwise clonable.
+static_assert(__is_bitwise_cloneable(int));
+static_assert(__is_bitwise_cloneable(int*));
+// array
+static_assert(__is_bitwise_cloneable(int[10]));
+
+// non-scalar types.
+static_assert(!__is_bitwise_cloneable(int&));
+
+
+struct Forward; // expected-note 2{{forward declaration of 'Forward'}}
+static_assert(!__is_bitwise_cloneable(Forward)); // expected-error 
{{incomplete type 'Forward' used in type trait expression}}
+
+struct Foo { int a; };
+static_assert(__is_bitwise_cloneable(Foo));
+
+struct DynamicClass { virtual int Foo(); };
+static_assert(__is_bitwise_cloneable(DynamicClass));
+
+struct Bar { int& b; }; // trivially copyable
+static_assert(__is_trivially_copyable(Bar));
+static_assert(__is_bitwise_cloneable(Bar));

hokein wrote:

Because of the reference member `int & b`.

Reference types are currently excluded in bitwise-cloneable types (references 
are just alias, and they cannot be reset once initialized).

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


[clang] [clang] CTAD alias: Emit a more descriptive diagnostic message when is_deducible constraint is evaluated to false. (PR #92389)

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

hokein wrote:

Thanks @mizvekov for the quick fix.

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


[clang] [clang] CTAD alias: Emit a more descriptive diagnostic message when is_deducible constraint is evaluated to false. (PR #92389)

2024-05-16 Thread Haojian Wu via cfe-commits

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


[clang] [clang] CTAD alias: Emit a more descriptive diagnostic message when is_deducible constraint is evaluated to false. (PR #92389)

2024-05-16 Thread Haojian Wu via cfe-commits


@@ -111,7 +111,7 @@ struct Foo {
 template 
 using Bar = Foo; // expected-note {{candidate template ignored: 
couldn't infer template argument 'X'}} \
// expected-note {{candidate template ignored: 
constraints not satisfied [with X = int]}} \
-   // expected-note {{because '__is_deducible}}
+   // expected-note {{can not deduce template 
arguments for 'Bar' from the type 'Foo'}}

hokein wrote:

ah, this was left when I adjusted the message. Done.

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


[clang] [clang] CTAD alias: Emit a more descriptive diagnostic message when is_deducible constraint is evaluated to false. (PR #92389)

2024-05-16 Thread Haojian Wu via cfe-commits

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

>From ada7f47eae6ef66a51cdeb91ab5aca0e188e5704 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Thu, 16 May 2024 14:05:57 +0200
Subject: [PATCH] [clang] CTAD alias: Emit a more descriptive diagnostic
 message when is_deducible constraint is evaluated to false.

Fixes https://github.com/llvm/llvm-project/issues/92225
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
 clang/lib/Sema/SemaConcept.cpp   | 7 +++
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 7 +++
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e648b503ac034..93fd5c16989da 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3003,6 +3003,8 @@ def 
note_single_arg_concept_specialization_constraint_evaluated_to_false : Note<
   "%select{and|because}0 %1 does not satisfy %2">;
 def note_atomic_constraint_evaluated_to_false_elaborated : Note<
   "%select{and|because}0 '%1' (%2 %3 %4) evaluated to false">;
+def note_is_deducible_constraint_evaluated_to_false : Note<
+  "cannot deduce template arguments for %0 from %1">;
 def err_constrained_virtual_method : Error<
   "virtual function cannot have a requires clause">;
 def err_trailing_requires_clause_on_deduction_guide : Error<
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 7bfec4e11f7aa..202dd86c67f62 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1162,6 +1162,13 @@ static void 
diagnoseWellFormedUnsatisfiedConstraintExpr(Sema ,
 break;
   }
 return;
+  } else if (auto *TTE = dyn_cast(SubstExpr);
+ TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
+assert(TTE->getNumArgs() == 2);
+S.Diag(SubstExpr->getSourceRange().getBegin(),
+   diag::note_is_deducible_constraint_evaluated_to_false)
+<< TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
+return;
   }
 
   S.Diag(SubstExpr->getSourceRange().getBegin(),
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp 
b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 7c186dc379c7b..21b2b8bff5002 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -111,7 +111,7 @@ struct Foo {
 template 
 using Bar = Foo; // expected-note {{candidate template ignored: 
couldn't infer template argument 'X'}} \
// expected-note {{candidate template ignored: 
constraints not satisfied [with X = int]}} \
-   // expected-note {{because '__is_deducible}}
+   // expected-note {{cannot deduce template 
arguments for 'Bar' from 'Foo'}}
 
 
 Bar s = {{1}}; // expected-error {{no viable constructor or deduction guide }}
@@ -138,7 +138,7 @@ template struct Foo { T c; };
 template
 using AFoo = Foo; // expected-note {{candidate template ignored: could not 
match 'Foo' against 'int'}} \
 // expected-note {{candidate template ignored: constraints 
not satisfied [with Y = int]}} \
-// expected-note {{because '__is_deducible(AFoo, 
Foo)' evaluated to false}} \
+// expected-note {{cannot deduce template arguments for 
'AFoo' from 'Foo'}} \
 // expected-note {{candidate function template not viable: 
requires 0 arguments, but 1 was provided}}
 
 AFoo s = {1}; // expected-error {{no viable constructor or deduction guide for 
deduction of template arguments of 'AFoo'}}
@@ -196,10 +196,9 @@ template  struct Foo { Foo(T); };
 
 template using AFoo = Foo;
 template concept False = false;
-// FIXME: emit a more descriptive diagnostic for "__is_deducible" constraint 
failure.
 template
 using BFoo = AFoo; // expected-note {{candidate template ignored: 
constraints not satisfied [with V = int]}} \
-  // expected-note {{because '__is_deducible(BFoo, Foo)' evaluated to false}} \
+  // expected-note {{cannot deduce template arguments for 
'BFoo' from 'Foo'}} \
   // expected-note {{candidate template ignored: could not 
match 'Foo' against 'int *'}}
 int i = 0;
 AFoo a1(); // OK, deduce Foo

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


[clang] [clang] CTAD alias: Emit a more descriptive diagnostic message when is_deducible constraint is evaluated to false. (PR #92389)

2024-05-16 Thread Haojian Wu via cfe-commits

https://github.com/hokein created 
https://github.com/llvm/llvm-project/pull/92389

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

>From 20294489121be7a68519280da8e144c2b9be398c Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Thu, 16 May 2024 14:05:57 +0200
Subject: [PATCH] [clang] CTAD alias: Emit a more descriptive diagnostic
 message when is_deducible constraint is evaluated to false.

Fixes https://github.com/llvm/llvm-project/issues/92225
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
 clang/lib/Sema/SemaConcept.cpp   | 7 +++
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 6 +++---
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e648b503ac034..04bf6ed2c52f5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3003,6 +3003,8 @@ def 
note_single_arg_concept_specialization_constraint_evaluated_to_false : Note<
   "%select{and|because}0 %1 does not satisfy %2">;
 def note_atomic_constraint_evaluated_to_false_elaborated : Note<
   "%select{and|because}0 '%1' (%2 %3 %4) evaluated to false">;
+def note_is_deducible_constraint_evaluated_to_false : Note<
+  "cannot deduce template arguments of %0 from %1">;
 def err_constrained_virtual_method : Error<
   "virtual function cannot have a requires clause">;
 def err_trailing_requires_clause_on_deduction_guide : Error<
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 7bfec4e11f7aa..202dd86c67f62 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1162,6 +1162,13 @@ static void 
diagnoseWellFormedUnsatisfiedConstraintExpr(Sema ,
 break;
   }
 return;
+  } else if (auto *TTE = dyn_cast(SubstExpr);
+ TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
+assert(TTE->getNumArgs() == 2);
+S.Diag(SubstExpr->getSourceRange().getBegin(),
+   diag::note_is_deducible_constraint_evaluated_to_false)
+<< TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
+return;
   }
 
   S.Diag(SubstExpr->getSourceRange().getBegin(),
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp 
b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 7c186dc379c7b..f7367d01bc2eb 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -111,7 +111,7 @@ struct Foo {
 template 
 using Bar = Foo; // expected-note {{candidate template ignored: 
couldn't infer template argument 'X'}} \
// expected-note {{candidate template ignored: 
constraints not satisfied [with X = int]}} \
-   // expected-note {{because '__is_deducible}}
+   // expected-note {{can not deduce template 
arguments for 'Bar' from the type 'Foo'}}
 
 
 Bar s = {{1}}; // expected-error {{no viable constructor or deduction guide }}
@@ -138,7 +138,7 @@ template struct Foo { T c; };
 template
 using AFoo = Foo; // expected-note {{candidate template ignored: could not 
match 'Foo' against 'int'}} \
 // expected-note {{candidate template ignored: constraints 
not satisfied [with Y = int]}} \
-// expected-note {{because '__is_deducible(AFoo, 
Foo)' evaluated to false}} \
+// expected-note {{cannot deduce template arguments for 
'AFoo' from 'Foo'}} \
 // expected-note {{candidate function template not viable: 
requires 0 arguments, but 1 was provided}}
 
 AFoo s = {1}; // expected-error {{no viable constructor or deduction guide for 
deduction of template arguments of 'AFoo'}}
@@ -199,7 +199,7 @@ template concept False = false;
 // FIXME: emit a more descriptive diagnostic for "__is_deducible" constraint 
failure.
 template
 using BFoo = AFoo; // expected-note {{candidate template ignored: 
constraints not satisfied [with V = int]}} \
-  // expected-note {{because '__is_deducible(BFoo, Foo)' evaluated to false}} \
+  // expected-note {{cannot deduce template arguments for 
'BFoo' from 'Foo'}} \
   // expected-note {{candidate template ignored: could not 
match 'Foo' against 'int *'}}
 int i = 0;
 AFoo a1(); // OK, deduce Foo

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

2024-05-16 Thread Haojian Wu via cfe-commits

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


[clang] [AST] RecursiveASTVisitor: Don't traverse the alias deduction guides in the default mode. (PR #91454)

2024-05-16 Thread Haojian Wu via cfe-commits

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


[clang] [clang-tools-extra] [clang] Fix CXXNewExpr end source location for 'new struct S' (PR #92266)

2024-05-16 Thread Haojian Wu via cfe-commits

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


[clang] [clang-tools-extra] [clang] Fix CXXNewExpr end source location for 'new struct S' (PR #92266)

2024-05-16 Thread Haojian Wu via cfe-commits


@@ -583,3 +583,8 @@ void NonADLCall3() {
   f(x);
 }
 } // namespace test_adl_call_three
+

hokein wrote:

nit: wrap the code within `namespace GH35300 { ...}`.

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


[clang] [clang-tools-extra] [clang] Fix CXXNewExpr end source location for 'new struct S' (PR #92266)

2024-05-16 Thread Haojian Wu via cfe-commits

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

thanks, still good.

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


[clang] [AST] RecursiveASTVisitor: Don't traverse the alias deduction guides in the default mode. (PR #91454)

2024-05-16 Thread Haojian Wu via cfe-commits

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

>From e560fe2bf2d4bdc07a71682aa4d3a4bee8730b80 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 8 May 2024 12:11:10 +0200
Subject: [PATCH 1/2] [AST] RecursiveASTVisitor: Don't traverse the alias
 deduction guides in default mode.

---
 clang/include/clang/AST/RecursiveASTVisitor.h | 28 --
 .../DeductionGuide.cpp| 89 +++
 2 files changed, 110 insertions(+), 7 deletions(-)
 create mode 100644 
clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp

diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index f9b145b4e86a5..2517189c95300 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -736,13 +736,27 @@ bool RecursiveASTVisitor::TraverseDecl(Decl *D) {
 
   // As a syntax visitor, by default we want to ignore declarations for
   // implicit declarations (ones not typed explicitly by the user).
-  if (!getDerived().shouldVisitImplicitCode() && D->isImplicit()) {
-// For an implicit template type parameter, its type constraints are not
-// implicit and are not represented anywhere else. We still need to visit
-// them.
-if (auto *TTPD = dyn_cast(D))
-  return TraverseTemplateTypeParamDeclConstraints(TTPD);
-return true;
+  if (!getDerived().shouldVisitImplicitCode()) {
+if (D->isImplicit()) {
+  // For an implicit template type parameter, its type constraints are not
+  // implicit and are not represented anywhere else. We still need to visit
+  // them.
+  if (auto *TTPD = dyn_cast(D))
+return TraverseTemplateTypeParamDeclConstraints(TTPD);
+  return true;
+}
+
+// Deduction guides for alias templates are always synthesized, so they
+// should not be traversed unless shouldVisitImplicitCode() returns true.
+//
+// It's important to note that checking the implicit bit is not efficient
+// for the alias case. For deduction guides synthesized from explicit
+// user-defined deduction guides, we must maintain the explicit bit to
+// ensure correct overload resolution.
+if (auto *FTD = dyn_cast(D))
+  if (llvm::isa_and_present(
+  FTD->getDeclName().getCXXDeductionGuideTemplate()))
+return true;
   }
 
   switch (D->getKind()) {
diff --git 
a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp 
b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp
new file mode 100644
index 0..abfdbaea4a615
--- /dev/null
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp
@@ -0,0 +1,89 @@
+//===- unittest/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "TestVisitor.h"
+#include 
+
+using namespace clang;
+
+namespace {
+
+class DeductionGuideVisitor
+: public ExpectedLocationVisitor {
+public:
+  DeductionGuideVisitor(bool ShouldVisitImplicitCode)
+  : ShouldVisitImplicitCode(ShouldVisitImplicitCode) {}
+  bool VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
+std::string Storage;
+llvm::raw_string_ostream Stream(Storage);
+D->print(Stream);
+Match(Stream.str(),D->getLocation());
+return true;
+  }
+
+  bool shouldVisitTemplateInstantiations() const {
+return false;
+  }
+
+  bool shouldVisitImplicitCode() const {
+return ShouldVisitImplicitCode;
+  }
+  bool ShouldVisitImplicitCode;
+};
+
+TEST(RecursiveASTVisitor, DeductionGuideNonImplicitMode) {
+  DeductionGuideVisitor Visitor(/*ShouldVisitImplicitCode*/ false);
+  // Verify that the synthezied deduction guide for alias is not visited in
+  // RAV's implicit mode.
+  Visitor.ExpectMatch("Foo(T) -> Foo", 11, 1);
+  Visitor.DisallowMatch("Bar(type-parameter-0-0) -> Foo", 14, 1);
+  EXPECT_TRUE(Visitor.runOver(
+R"cpp(
+template 
+concept False = true;
+
+template  
+struct Foo { 
+  Foo(T);
+};
+
+template requires False
+Foo(T) -> Foo;
+
+template 
+using Bar = Foo;
+Bar s(1); 
+   )cpp"
+  , DeductionGuideVisitor::Lang_CXX2a));
+}
+
+TEST(RecursiveASTVisitor, DeductionGuideImplicitMode) {
+  DeductionGuideVisitor Visitor(/*ShouldVisitImplicitCode*/ true);
+  Visitor.ExpectMatch("Foo(T) -> Foo", 11, 1);
+  Visitor.ExpectMatch("Bar(type-parameter-0-0) -> Foo", 14, 1);
+  EXPECT_TRUE(Visitor.runOver(
+R"cpp(
+template 
+concept False = true;
+
+template  
+struct Foo { 
+  Foo(T);
+};
+
+template requires False
+Foo(T) -> Foo;
+
+template 
+using Bar = Foo;
+Bar s(1); 
+   )cpp"
+  , DeductionGuideVisitor::Lang_CXX2a));
+}
+
+} // end anonymous namespace

>From 

[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-16 Thread Haojian Wu via cfe-commits


@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+// Scalar types are bitwise clonable.
+static_assert(__is_bitwise_cloneable(int));
+static_assert(__is_bitwise_cloneable(int*));
+// array
+static_assert(__is_bitwise_cloneable(int[10]));
+
+// non-scalar types.
+static_assert(!__is_bitwise_cloneable(int&));
+
+
+struct Forward; // expected-note 2{{forward declaration of 'Forward'}}
+static_assert(!__is_bitwise_cloneable(Forward)); // expected-error 
{{incomplete type 'Forward' used in type trait expression}}
+
+struct Foo { int a; };
+static_assert(__is_bitwise_cloneable(Foo));
+
+struct DynamicClass { virtual int Foo(); };
+static_assert(__is_bitwise_cloneable(DynamicClass));
+
+struct Bar { int& b; }; // trivially copyable
+static_assert(__is_trivially_copyable(Bar));
+static_assert(__is_bitwise_cloneable(Bar));

hokein wrote:

This is a tricky bit.

The question arises: should we consider all trivially copyable types to be 
bitwise cloneable? My inclination is to say yes. Since memcpy is `safe` on all 
trivially copyable types, it's probably a good idea to ensure that 
bitwise_clonable covers as many types as possible.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-16 Thread Haojian Wu via cfe-commits


@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+// Scalar types are bitwise clonable.
+static_assert(__is_bitwise_cloneable(int));
+static_assert(__is_bitwise_cloneable(int*));
+// array
+static_assert(__is_bitwise_cloneable(int[10]));
+
+// non-scalar types.
+static_assert(!__is_bitwise_cloneable(int&));
+
+
+struct Forward; // expected-note 2{{forward declaration of 'Forward'}}
+static_assert(!__is_bitwise_cloneable(Forward)); // expected-error 
{{incomplete type 'Forward' used in type trait expression}}
+
+struct Foo { int a; };
+static_assert(__is_bitwise_cloneable(Foo));
+
+struct DynamicClass { virtual int Foo(); };
+static_assert(__is_bitwise_cloneable(DynamicClass));

hokein wrote:

Done.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-16 Thread Haojian Wu via cfe-commits


@@ -2718,6 +2718,36 @@ bool QualType::isTriviallyCopyableType(const ASTContext 
) const {
  /*IsCopyConstructible=*/false);
 }
 
+bool QualType::isBitwiseCloneableType(const ASTContext & Context) const {
+  QualType CanonicalType = getCanonicalType();
+  if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType())
+return false;
+  // Trivially copyable types are bitwise clonable, e.g. scalar types.
+  if (CanonicalType.isTriviallyCopyableType(Context))
+return true;
+
+  if (CanonicalType->isArrayType())
+return Context.getBaseElementType(CanonicalType)
+.isBitwiseCloneableType(Context);
+
+  if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
+for (auto Base : RD->bases())
+  if (!Base.getType().isBitwiseCloneableType(Context))
+return false;
+for (auto VBase : RD->vbases())
+  if (!VBase.getType().isBitwiseCloneableType(Context))
+return false;
+
+for (auto *const Field : RD->fields()) {
+  QualType T = Context.getBaseElementType(Field->getType());

hokein wrote:

Switched to `isBitwiseCloneableType(Field->getType())`.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-16 Thread Haojian Wu via cfe-commits


@@ -2718,6 +2718,36 @@ bool QualType::isTriviallyCopyableType(const ASTContext 
) const {
  /*IsCopyConstructible=*/false);
 }
 
+bool QualType::isBitwiseCloneableType(const ASTContext & Context) const {
+  QualType CanonicalType = getCanonicalType();
+  if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType())
+return false;
+  // Trivially copyable types are bitwise clonable, e.g. scalar types.
+  if (CanonicalType.isTriviallyCopyableType(Context))
+return true;
+
+  if (CanonicalType->isArrayType())
+return Context.getBaseElementType(CanonicalType)
+.isBitwiseCloneableType(Context);
+
+  if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
+for (auto Base : RD->bases())
+  if (!Base.getType().isBitwiseCloneableType(Context))

hokein wrote:

Good point, added a FIXME (we could use an extra bit in the class definition 
class to cache the result).

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-16 Thread Haojian Wu via cfe-commits

https://github.com/hokein commented:

thanks for the review.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-16 Thread Haojian Wu via cfe-commits


@@ -3958,6 +3958,50 @@ Note that the `size` argument must be a compile time 
constant.
 
 Note that this intrinsic cannot yet be called in a ``constexpr`` context.
 
+``__is_bitwise_cloneable``
+-
+
+A type trait is used to check whether a type can be safely copied by memcpy.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  bool __is_bitwise_cloneable(Type)
+
+** Example of Use**:
+
+.. code-block:: c++
+
+  // Return a cloned object of the given default instance.
+  Foo* Clone(const Foo* default_instance, char* buffer, unsigned size) {
+if constexpr __is_bitwise_cloneable(decltype(*default_instance)) {
+  // Fast path via memcopy, without calling class constructor.
+  memcpy(buffer, default_instance, size);
+  // Explicitly start the lifetime of the cloned object.
+  return __builtin_start_object_lifetime(reinterpret_cast(buffer));
+}
+// Fallback the operator new, which invoke the class constructor.
+return new(buffer) Foo(*default_instance);
+  }
+
+**Description**:
+
+It is common for library owners to perform memcpy/memmove on types that aren't
+trivally copyable for performance reason. However, according to the C++ 
standard,

hokein wrote:

Done.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-16 Thread Haojian Wu via cfe-commits

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-05-16 Thread Haojian Wu via cfe-commits

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

>From 10d06e728d836f4aaad7dbf1a6b06b57e4092bb1 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 25 Mar 2024 15:10:51 +0100
Subject: [PATCH 1/3] [clang] Implement a bitwise_copyable builtin type trait.

This patch implements a `__is_bitwise_copyable` builtin in clang.

The bitwise copyable types act as the trivially copyable types, but
they support a wider range of types (e.g. classes with virtual methods) --
their underlying types can be safely copied by `memcopy` or `memmove`,
the clang compiler guarantees that both source and destination objects
have the same *object* representations after the copy operation, and the
lifetime of the destination object implicitly starts.

A particular use case of this builtin is to clone an object via memcopy
(without running the constructor):

```
Message* clone(const Message* src, char* buffer, int size) {
  if constexpr __is_bitwise_copyable(Message) {
// bitwise copy to buffer, and implicitly create objects at the buffer
__builtin_memcpy(buffer, src, size);
return std::launder(reinterpret_cast(buffer));
  }
  // Fallback the operator new, which calls the constructor to start the 
lifetime.
  return new(buffer) Message(src);
}
```

Note that the definition of bitwise copyable is not tied to the Rule Of
Five, so users of this builtin must guarantee that program semantic constraints
are satisfied, e.g. no double resource deallocations.

Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy
---
 clang/include/clang/AST/Type.h| 12 +
 clang/include/clang/Basic/TokenKinds.def  |  1 +
 clang/lib/AST/Type.cpp| 23 
 clang/lib/Sema/SemaExprCXX.cpp|  4 +++
 .../SemaCXX/builtin-is-bitwise-copyable.cpp   | 26 +++
 5 files changed, 66 insertions(+)
 create mode 100644 clang/test/SemaCXX/builtin-is-bitwise-copyable.cpp

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index e6643469e0b33..ff60f1c4b3520 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1120,6 +1120,18 @@ class QualType {
   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
   bool isTriviallyCopyableType(const ASTContext ) const;
 
+  /// Return true if this is a bitwise copyable type.
+  ///
+  /// This is an extension in clang: bitwise copyable types act as trivially
+  /// copyable types, underlying bytes of bitwise copyable type can be safely
+  /// copied by memcpy or memmove. Clang guarantees that both source and
+  /// destination objects have the same **object** representations after the
+  /// copy, and the lifetime of the destination object implicitly starts.
+  ///
+  /// bitwise copyable types cover a wider range of types, e.g. classes with
+  /// virtual methods.
+  bool isBitwiseCopyableType(const ASTContext ) const;
+
   /// Return true if this is a trivially copyable type
   bool isTriviallyCopyConstructibleType(const ASTContext ) const;
 
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 56c4b17f769d7..ce2298543fac6 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -527,6 +527,7 @@ TYPE_TRAIT_2(__is_pointer_interconvertible_base_of, 
IsPointerInterconvertibleBas
 #include "clang/Basic/TransformTypeTraits.def"
 
 // Clang-only C++ Type Traits
+TYPE_TRAIT_1(__is_bitwise_copyable, IsBitwiseCopyable, KEYCXX)
 TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX)
 TYPE_TRAIT_1(__is_trivially_equality_comparable, 
IsTriviallyEqualityComparable, KEYCXX)
 TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX)
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e31741cd44240..5c0b89545a92b 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2731,6 +2731,29 @@ bool QualType::isTriviallyCopyableType(const ASTContext 
) const {
  /*IsCopyConstructible=*/false);
 }
 
+bool QualType::isBitwiseCopyableType(const ASTContext & Context) const {
+  QualType CanonicalType = getCanonicalType();
+  if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType())
+return false;
+  // Trivially copyable types are bitwise copyable, e.g. scalar types.
+  if (CanonicalType.isTriviallyCopyableType(Context))
+return true;
+
+  if (CanonicalType->isArrayType())
+return Context.getBaseElementType(CanonicalType)
+.isBitwiseCopyableType(Context);
+
+  if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
+for (auto *const Field : RD->fields()) {
+  QualType T = Context.getBaseElementType(Field->getType());
+  if (!T.isBitwiseCopyableType(Context))
+return false;
+}
+return true;
+  }
+  return false;
+}
+
 bool QualType::isTriviallyCopyConstructibleType(
 const 

  1   2   3   4   5   6   7   8   9   10   >