[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-23 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> We can't go back from non-dependent into dependent.

Sorry, maybe I use the word 'transform' that makes you confused. Actually, what 
I did in `TransformTemplateName` is transforming a `QualifiedTemplateName` 
which is dependent due to its qualifier dependency and dependent `DeclContext`  
to a `DependentTemplateName`. Although the transformed `DependentTemplateName` 
is also dependent, its qualifier is independent. This make the condition 
https://github.com/llvm/llvm-project/blob/e7622ab4721141d9e6af6041fa7f9bbc1029e9aa/clang/lib/Sema/SemaTemplate.cpp#L4691
 false which holds before this patch. This time the flow goes into 
https://github.com/llvm/llvm-project/blob/e7622ab4721141d9e6af6041fa7f9bbc1029e9aa/clang/lib/Sema/SemaTemplate.cpp#L4741-L4746
 and do the specialization.

> Can you elaborate on that?

I just tried to create `DependentTemplateName` at 
https://github.com/llvm/llvm-project/blob/e7622ab4721141d9e6af6041fa7f9bbc1029e9aa/clang/lib/Sema/SemaTemplate.cpp#L297-L298
 a few days ago and break several cases which contains the code related to 
partial specialization. But I didn't dig into the code and give up that 
approach.

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


[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-22 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> I still don't understand why you are saying we didn't or can't build a 
> DependentTemplateSpecializationType instead.

I mean we can transform `QualifiedTemplateName` to `DependentTemplateName` and 
this is what this patch does. If we build a `DependentTemplateName` instead of 
`QualifiedTemplateName` earlier would affect the code in partial specialization 
like:
```cpp
template
struct A::B
```


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


[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-22 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94725

>From 4e9e322a82e636783d2ba0ccda92f3547d557a64 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/Sema/TreeTransform.h| 19 ++
 .../SemaCXX/many-template-parameter-lists.cpp |  6 +++---
 .../PR12884_original_no_crash.cpp | 20 +++
 clang/test/SemaTemplate/PR91677.cpp   | 14 +
 .../SemaTemplate/typename-specifier-3.cpp |  7 ---
 6 files changed, 61 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR12884_original_no_crash.cpp
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7ac0fa0141b47..8f217990a494c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -914,6 +914,7 @@ Bug Fixes to C++ Support
 - Clang now diagnoses explicit specializations with storage class specifiers 
in all contexts.
 - Fix an assertion failure caused by parsing a lambda used as a default 
argument for the value of a
   forward-declared class. (#GH93512).
+- Clang now transforms qualifier of template name. (#91677).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index cf4e80399632b..6fd9f20647b0b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,25 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (getDerived().AlwaysRebuild() ||
+  QualifierLoc != TransformedQualifierLoc) {
+QualifierSS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+QualifierSS, QTN->hasTemplateKeyword() ? SourceLocation() : 
NameLoc,
+*Template->getIdentifier(), NameLoc, ObjectType,
+FirstQualifierInScope, /*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..4f447be06b926 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{dependent nested name specifier 
'A::template B::template C::template D::template E::' for friend 
class declaration is not supported; turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR12884_original_no_crash.cpp 
b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
new file mode 100644
index 0..f2b6f6e28c2f9
--- /dev/null
+++ b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+namespace PR12884_original {
+  template  struct A {
+struct B {
+  template  struct X {};
+  typedef int arg;
+};
+struct C {
+  typedef B::X x; // expected-error{{typename specifier 
refers to non-type member 'arg' in 'PR12884_original::A::B'}}
+};
+  };
+
+  template <> struct A::B {
+template  struct X {};
+static const int arg = 0; // expected-note{{referenced member 'arg' is 
declared here}}
+  };
+
+  A::C::x a; // expected-note{{in instantiation of member class 
'PR12884_original::A::C' requested here}}
+}
diff 

[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-22 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94725

>From 8359bac8e59c6b5ebc6500042dc473c3f4245c08 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/Sema/TreeTransform.h| 19 ++
 .../SemaCXX/many-template-parameter-lists.cpp |  6 +++---
 .../PR12884_original_no_crash.cpp | 20 +++
 clang/test/SemaTemplate/PR91677.cpp   | 14 +
 .../SemaTemplate/typename-specifier-3.cpp |  7 ---
 6 files changed, 61 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR12884_original_no_crash.cpp
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7ac0fa0141b47..8f217990a494c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -914,6 +914,7 @@ Bug Fixes to C++ Support
 - Clang now diagnoses explicit specializations with storage class specifiers 
in all contexts.
 - Fix an assertion failure caused by parsing a lambda used as a default 
argument for the value of a
   forward-declared class. (#GH93512).
+- Clang now transforms qualifier of template name. (#91677).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index cf4e80399632b..171f64d35b8cf 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,25 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (getDerived().AlwaysRebuild() ||
+  QualifierLoc != TransformedQualifierLoc) {
+QualifierSS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+QualifierSS, QTN->hasTemplateKeyword() ? NameLoc : 
SourceLocation(),
+*Template->getIdentifier(), NameLoc, ObjectType,
+FirstQualifierInScope, /*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..bd016894d75e0 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{dependent nested name specifier 
'A::template template B::template template C::template template 
D::template template E::' for friend class declaration is not supported; 
turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR12884_original_no_crash.cpp 
b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
new file mode 100644
index 0..f2b6f6e28c2f9
--- /dev/null
+++ b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+namespace PR12884_original {
+  template  struct A {
+struct B {
+  template  struct X {};
+  typedef int arg;
+};
+struct C {
+  typedef B::X x; // expected-error{{typename specifier 
refers to non-type member 'arg' in 'PR12884_original::A::B'}}
+};
+  };
+
+  template <> struct A::B {
+template  struct X {};
+static const int arg = 0; // expected-note{{referenced member 'arg' is 
declared here}}
+  };
+
+  A::C::x a; // expected-note{{in instantiation of member class 

[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-22 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94725

>From 4b1d55c56f969e926645a856ba67e289776326a8 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/Sema/TreeTransform.h| 19 ++
 .../SemaCXX/many-template-parameter-lists.cpp |  6 +++---
 .../PR12884_original_no_crash.cpp | 20 +++
 clang/test/SemaTemplate/PR91677.cpp   | 14 +
 .../SemaTemplate/typename-specifier-3.cpp |  7 ---
 6 files changed, 61 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR12884_original_no_crash.cpp
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7ac0fa0141b47..8f217990a494c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -914,6 +914,7 @@ Bug Fixes to C++ Support
 - Clang now diagnoses explicit specializations with storage class specifiers 
in all contexts.
 - Fix an assertion failure caused by parsing a lambda used as a default 
argument for the value of a
   forward-declared class. (#GH93512).
+- Clang now transforms qualifier of template name. (#91677).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index cf4e80399632b..8beb94b0b3c98 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,25 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (getDerived().AlwaysRebuild() ||
+  QualifierLoc != TransformedQualifierLoc) {
+SS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+SS, QTN->hasTemplateKeyword() ? NameLoc : SourceLocation(),
+*Template->getIdentifier(), NameLoc, ObjectType,
+FirstQualifierInScope, /*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..b111d9e91de1d 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{A::template B::template 
C::template D::template template E::' for friend class declaration is 
not supported; turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR12884_original_no_crash.cpp 
b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
new file mode 100644
index 0..f2b6f6e28c2f9
--- /dev/null
+++ b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+namespace PR12884_original {
+  template  struct A {
+struct B {
+  template  struct X {};
+  typedef int arg;
+};
+struct C {
+  typedef B::X x; // expected-error{{typename specifier 
refers to non-type member 'arg' in 'PR12884_original::A::B'}}
+};
+  };
+
+  template <> struct A::B {
+template  struct X {};
+static const int arg = 0; // expected-note{{referenced member 'arg' is 
declared here}}
+  };
+
+  A::C::x a; // expected-note{{in instantiation of member class 
'PR12884_original::A::C' requested here}}
+}
diff --git a/clang/test/SemaTemplate/PR91677.cpp 

[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-22 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

@mizvekov After looking into the code, I think we should transform qualifier in 
TST. Consider the following code:
```cpp
template 
t1::template t2 f1();

void f2() {
  f1();
}
```
`TemplateSpecializationType` of `t2` whose `Template` is a 
`QualifiedTemplateName`(`t1::`) will be dependent if we didn't transform the 
qualifier since its qualifier and `DeclContext` are both dependent and it 
wouldn't be specialized in `Sema::CheckTemplateIdType` due to its name 
dependency. Transform the qualifier and rebuild the `TemplateName` as a 
`DependentTemplateName` is also consistent  with what it is before cpp20(`t2` 
is a `DependentTemplateName`) which needs a `typename` keyword(`typename 
t1::template t2`).
> The fact that this change somehow affects program semantics is still 
> unexpected and unexplained.

The case in `clang/test/SemaCXX/many-template-parameter-lists.cpp` is affected 
is because the qualifier didn't be transformed and we can't find the 
instantiation of the declaration(`X`) which will not happen after this patch. 
This case is also accepted by gcc. The other cases are expected or explained in 
the comments.

>If I had to take a guess, there is something wrong in the dependency 
>computation for the NNS. Have you checked that?

I didn't find some problems in dependency computation for the NNS.

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


[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-22 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94725

>From 70928fcec829b6cb02fd9fe19b214518c872eea6 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/Sema/TreeTransform.h| 18 +
 .../SemaCXX/many-template-parameter-lists.cpp |  6 +++---
 .../PR12884_original_no_crash.cpp | 20 +++
 clang/test/SemaTemplate/PR91677.cpp   | 14 +
 .../SemaTemplate/typename-specifier-3.cpp |  7 ---
 6 files changed, 60 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR12884_original_no_crash.cpp
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7ac0fa0141b47..8f217990a494c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -914,6 +914,7 @@ Bug Fixes to C++ Support
 - Clang now diagnoses explicit specializations with storage class specifiers 
in all contexts.
 - Fix an assertion failure caused by parsing a lambda used as a default 
argument for the value of a
   forward-declared class. (#GH93512).
+- Clang now transforms qualifier of template name. (#91677).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index cf4e80399632b..b3872a18da4fa 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,24 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (getDerived().AlwaysRebuild() ||
+  QualifierLoc != TransformedQualifierLoc) {
+SS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+SS, SourceLocation(), *Template->getIdentifier(), NameLoc,
+ObjectType, FirstQualifierInScope, 
/*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..b5d954986dd4f 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{dependent nested name specifier 
'A::B::C::D::template E::' for friend class declaration is not 
supported; turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR12884_original_no_crash.cpp 
b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
new file mode 100644
index 0..f2b6f6e28c2f9
--- /dev/null
+++ b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+namespace PR12884_original {
+  template  struct A {
+struct B {
+  template  struct X {};
+  typedef int arg;
+};
+struct C {
+  typedef B::X x; // expected-error{{typename specifier 
refers to non-type member 'arg' in 'PR12884_original::A::B'}}
+};
+  };
+
+  template <> struct A::B {
+template  struct X {};
+static const int arg = 0; // expected-note{{referenced member 'arg' is 
declared here}}
+  };
+
+  A::C::x a; // expected-note{{in instantiation of member class 
'PR12884_original::A::C' requested here}}
+}
diff --git a/clang/test/SemaTemplate/PR91677.cpp 
b/clang/test/SemaTemplate/PR91677.cpp
new file mode 

[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-22 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94725

>From 8327ee1afef04480a1a18eef169f24906e432e87 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/Sema/TreeTransform.h| 18 +
 .../SemaCXX/many-template-parameter-lists.cpp |  6 +++---
 .../PR12884_original_no_crash.cpp | 20 +++
 clang/test/SemaTemplate/PR91677.cpp   | 14 +
 clang/test/SemaTemplate/instantiate-scope.cpp |  5 +
 .../SemaTemplate/typename-specifier-3.cpp |  7 ---
 7 files changed, 61 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR12884_original_no_crash.cpp
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7ac0fa0141b47..8f217990a494c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -914,6 +914,7 @@ Bug Fixes to C++ Support
 - Clang now diagnoses explicit specializations with storage class specifiers 
in all contexts.
 - Fix an assertion failure caused by parsing a lambda used as a default 
argument for the value of a
   forward-declared class. (#GH93512).
+- Clang now transforms qualifier of template name. (#91677).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index cf4e80399632b..b3872a18da4fa 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,24 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (getDerived().AlwaysRebuild() ||
+  QualifierLoc != TransformedQualifierLoc) {
+SS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+SS, SourceLocation(), *Template->getIdentifier(), NameLoc,
+ObjectType, FirstQualifierInScope, 
/*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..b5d954986dd4f 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{dependent nested name specifier 
'A::B::C::D::template E::' for friend class declaration is not 
supported; turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR12884_original_no_crash.cpp 
b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
new file mode 100644
index 0..f2b6f6e28c2f9
--- /dev/null
+++ b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+namespace PR12884_original {
+  template  struct A {
+struct B {
+  template  struct X {};
+  typedef int arg;
+};
+struct C {
+  typedef B::X x; // expected-error{{typename specifier 
refers to non-type member 'arg' in 'PR12884_original::A::B'}}
+};
+  };
+
+  template <> struct A::B {
+template  struct X {};
+static const int arg = 0; // expected-note{{referenced member 'arg' is 
declared here}}
+  };
+
+  A::C::x a; // expected-note{{in instantiation of member class 
'PR12884_original::A::C' requested here}}
+}
diff --git 

[clang] [Clang][Sema] Skip checking anonymous enum in using enum declaration (PR #87144)

2024-06-16 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> Hi @jcsxky , I fetched and rebased to origin/main just now (6/16/2024 at 
> 4:30pm Central US time), and rebuilt - and I see the crash. Did you try 
> rebasing to latest source and rebuilding?
> 
> `$ clang --analyze -Xclang -analyzer-config -Xclang 
> experimental-enable-naive-ctu-analysis=true -Xclang -analyzer-config -Xclang 
> ctu-dir=ctudir -Xclang -analyzer-config -Xclang display-ctu-progress=true 
> test.cpp` `CTU loaded AST file: bstrwrap.cpp.ast` `clang: 
> clang/lib/AST/Decl.cpp:4045: void 
> clang::FunctionDecl::setDescribedFunctionTemplate(clang::FunctionTemplateDecl*):
>  Assertion "TemplateOrSpecialization.isNull() && "Member function is already 
> a specialization" failed.` `PLEASE submit a bug report to 
> https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, 
> preprocessed source, and associated run script.`
> 
> ...

Yes, I have tried the latest source, but it still looks good. Also, I didn't 
see the output `CTU loaded AST file: bstrwrap.cpp.ast`. I tried this command 
`clang-extdef-mapping test.cpp` and output is `11:c:@F@test0#` which is 
different from yours(`f` and `F`, output of the other file is identical). This 
time I see `CTU loaded AST file: bstrwrap.cpp.ast` but still has no crash. 
@vabridgers Can you check your output with command `clang-extdef-mapping 
test.cpp`?

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


[clang] [Clang][Sema] Skip checking anonymous enum in using enum declaration (PR #87144)

2024-06-16 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

```cpp
ls
bstrwrap.cpp  bstrwrap.h  ctudir  test.cpp  test.plist  test.sh

cat bstrwrap.cpp
#include "bstrwrap.h"
#include 
Bstrlib::CBString::CBString () {
}

cat bstrwrap.h
#include 
namespace Bstrlib {
struct CBString {
 CBString ();
};
extern std::istream& getline (void);
}

cat test.cpp
#include "bstrwrap.h"
int test0 (void) {
 Bstrlib::CBString c0;
 return 0;
}

cat ctudir/externalDefMap.txt 
11:c:@f@test0# test.cpp.ast
35:c:@n@Bstrlib@S@CBString@F@CBString# bstrwrap.cpp.ast

~/llvm-project/build/bin/clang test.cpp -emit-ast -D__clang_analyzer__ -w -o 
ctudir/test.cpp.ast
~/llvm-project/build/bin/clang bstrwrap.cpp -emit-ast -D__clang_analyzer__ -w 
-o ctudir/bstrwrap.cpp.ast
~/llvm-project/build/bin/clang --analyze -Xclang -analyzer-config -Xclang 
experimental-enable-naive-ctu-analysis=true -Xclang -analyzer-config -Xclang 
ctu-dir=ctudir -Xclang -analyzer-config -Xclang display-ctu-progress=true 
test.cpp
```
I have tested locally using main branch with clang and it has no crash. Maybe I 
missed something? Could you please take a second look? @vabridgers 

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


[clang] [Clang][Sema] Skip checking anonymous enum in using enum declaration (PR #87144)

2024-06-16 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> This change has caused a regression in one of our systems integration tests 
> that test static analysis for the bstring lib project 
> (https://github.com/websnarf/bstrlib) with cross translation unit analysis 
> enabled. Unfortunately I do not have a simple reproducer that stands alone 
> just using clang, but I do have a reproducer that uses CodeChecker and can 
> paste in the crash signature here. Please consider reverting the change until 
> a proper fix can be made and this issue is addressed.
> 
> ```
> bstrwrap.cpp
>   1 #include "bstrwrap.h"
>   2 #include 
>   3
>   4 Bstrlib::CBString::CBString () {
>   5 } 
> 
> bstrwrap.h
>   1 #include 
>   2
>   3 namespace Bstrlib {
>   4 struct CBString {  
>   5CBString ();
>   6 };
>   7
>   8 extern std::istream& getline (std::istream& sin, CBString& b, char 
> terminator='\n');
>   9
>  10 } // namespace Bstrlib
> 
> 
> test.cpp
>   1 #include "bstrwrap.h"
>   2
>   3 int test0 (void) {
>   4   Bstrlib::CBString c0;
>   5   return 0;
>   6 }
> ```
> 
> Using CodeChecker from https://github.com/Ericsson/codechecker, Log the build
> 
> `CodeChecker log -b "g++ -c test.cpp bstrwrap.cpp" -o comp.json`
> 
> Repro step
> 
> ```
> ``env PATH=:$PATH CC_ANALYZERS_FROM_PATH=1 CodeChecker 
> analyze comp.json  --clean  --ctu -o report --analyzers clangsa``
> ```
> 
> The crash signature, appears to be crashing in AST Import.
> 
> ```
> 1.   parser at end of file
> 2.  While analyzing stack:
> #0 Calling test0()
> 3.  test.cpp:4:21: Error evaluating statement
> 4.  test.cpp:4:21: Error evaluating statement
>  #0 0x03cb7248 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
> (clang-19+0x3cb7248)
>  #1 0x03cb4f2c llvm::sys::CleanupOnSignal(unsigned long) 
> (clang-19+0x3cb4f2c)
>  #2 0x03bfd308 CrashRecoverySignalHandler(int) 
> CrashRecoveryContext.cpp:0:0
>  #3 0x7f9e5d53d630 __restore_rt sigaction.c:0:0
>  #4 0x7f9e5af39387 raise (/lib64/libc.so.6+0x36387)
>  #5 0x7f9e5af3aa78 abort (/lib64/libc.so.6+0x37a78)
>  #6 0x7f9e5af321a6 __assert_fail_base (/lib64/libc.so.6+0x2f1a6)
>  #7 0x7f9e5af32252 (/lib64/libc.so.6+0x2f252)
>  #8 0x072ada26 
> clang::FunctionDecl::setDescribedFunctionTemplate(clang::FunctionTemplateDecl*)
>  (clang-19+0x72ada26)
>  #9 0x07190a56 
> clang::ASTNodeImporter::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl*)
>  (clang-19+0x7190a56)
> #10 0x0716e998 clang::declvisitor::Base clang::ASTNodeImporter, llvm::Expected>::Visit(clang::Decl*) 
> crtstuff.c:0:0
> #11 0x0716eedb clang::ASTImporter::Import(clang::Decl*) 
> (clang-19+0x716eedb)
> #12 0x07172108 std::conditional clang::Decl>, llvm::Expected, 
> llvm::Expected>::type 
> clang::ASTNodeImporter::import(clang::Decl*) crtstuff.c:0:0
> #13 0x0717d072 
> clang::ASTNodeImporter::ImportDeclContext(clang::DeclContext*, bool) 
> (clang-19+0x717d072)
> #14 0x0718677b 
> clang::ASTNodeImporter::VisitNamespaceDecl(clang::NamespaceDecl*) 
> (clang-19+0x718677b)
> #15 0x0716ea38 clang::declvisitor::Base clang::ASTNodeImporter, llvm::Expected>::Visit(clang::Decl*) 
> crtstuff.c:0:0
> #16 0x0716eedb clang::ASTImporter::Import(clang::Decl*) 
> (clang-19+0x716eedb)
> #17 0x07175146 
> clang::ASTImporter::Import(clang::NestedNameSpecifier*) (clang-19+0x7175146)
> #18 0x0717a0bb 
> clang::ASTNodeImporter::VisitElaboratedType(clang::ElaboratedType const*) 
> (clang-19+0x717a0bb)
> #19 0x07174945 clang::TypeVisitor llvm::Expected>::Visit(clang::Type const*) crtstuff.c:0:0
> #20 0x07174c07 clang::ASTImporter::Import(clang::Type const*) 
> (clang-19+0x7174c07)
> #21 0x07175bd7 clang::ASTImporter::Import(clang::QualType) 
> (clang-19+0x7175bd7)
> #22 0x07177e20 
> clang::ASTNodeImporter::VisitLValueReferenceType(clang::LValueReferenceType 
> const*) (clang-19+0x7177e20)
> ```

Looks like ASTImporter issue. Could you please provider a reproducer using 
clang only? That would be better to catch the issue. Just reverting this patch 
may not crash any more, but it would lead to incorrect AST be imported and 
influenced the accuracy of static analysis.

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


[clang] [clang] SourceLocIdentKind::Function should not be dependent (PR #94942)

2024-06-16 Thread Qizhi Hu via cfe-commits

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


[clang] [clang] SourceLocIdentKind::Function should not be dependent (PR #94942)

2024-06-16 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> So, looked into this more. You are correct that `Function` needs not be 
> dependent because we only ever show the name of the function unqualified. 
> However, `FunctionSig` does. Here is an example of what we are trying to 
> preserve https://godbolt.org/z/M3eTa8nn5 (the clang 17 behavior was incorrect)
> 
> I apologize for not realizing earlier that your change was actually sensible 
> in the case of `Function`

Never mind! After looking into the code a little bit more, `FunctionSig` indeed 
needs to be dependent.
```cpp
template
constexpr int g() {
  return N;
}

template 
struct S {
void f(auto) {
constexpr const char* F = __builtin_FUNCSIG();
static_assert(__builtin_strlen(F)==g<__builtin_strlen(F)>());
}

};

void f(){
S{}.f(0);
}
```
However, it still crash when we changed from  `__builtin_FUNCTION` to 
`__builtin_FUNCSIG` in the testcase from 
https://github.com/llvm/llvm-project/issues/80210. The underlying issue is that 
`CurContext` is `FunctionTemplateDecl` which is dependent and we used it as 
`ParentContext` of `SourceLocExpr` when transforming `decltype` of function 
`construct_at`. This makes transformed return type of `construct_at` dependent 
which is not what we want. I will close this patch since it  doesn't resolve 
the underlying issue.  Thanks for your time for the review! @cor3ntin 








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


[clang] [clang] SourceLocIdentKind::Function should not be dependent (PR #94942)

2024-06-13 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

```cpp
struct BasicPersistent;

struct SourceLocation {
  static constexpr const char* Current(const char * func = 
__builtin_FUNCTION()) {
return func;
}
};

template  BasicPersistent &&__declval(int);
template  auto declval() -> decltype(__declval<_Tp>(0));
template  _Tp forward;

template 
auto construct_at(_Tp *, _Args...) -> decltype(new _Tp(declval<_Args>()...)) {
constexpr auto *F = SourceLocation::Current();
static_assert(__builtin_strlen(F) == 12);
return 0;
}

template  struct allocator;
template  struct allocator_traits;
template  struct allocator_traits> {
  using pointer = _Tp *;
  template 
  static void construct(_Up __p, _Args...) {
construct_at(__p, forward<_Args>...);
  }
};

struct __alloc_traits : allocator_traits> {
} push_back___x;

__alloc_traits::pointer _M_impl_0;
template  void emplace_back(_Args...) {
  __alloc_traits::construct(_M_impl_0, forward<_Args>...);
}

struct BasicPersistent {
  BasicPersistent(BasicPersistent &&,
  const char* = SourceLocation::Current()) {}
};

void CFXJSE_EngineAddObjectToUpArray() { emplace_back(push_back___x); }
```
I modify the testcase as above and I think we just need to make dependent if 
Kind is `SourceLocIdentKind::SourceLocStruct`. Could you please take another 
look? @cor3ntin 

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


[clang] [clang] SourceLocIdentKind::Function should not be dependent (PR #94942)

2024-06-13 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94942

>From 96f4e2a5c82296b61e53189135d88a2d2b0da9f4 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Mon, 10 Jun 2024 16:53:54 +0800
Subject: [PATCH] [clang] SourceLocIdentKind::Function should not be dependent

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/include/clang/AST/Expr.h|  2 --
 clang/test/CodeGenCXX/PR80210.cpp | 34 +++
 3 files changed, 35 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/PR80210.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cf1ba02cbc4b2..efe78139de6fa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -846,6 +846,7 @@ Bug Fixes to C++ Support
 - Fix a crash caused by improper use of ``__array_extent``. (#GH80474)
 - Fixed several bugs in capturing variables within unevaluated contexts. 
(#GH63845), (#GH67260), (#GH69307),
   (#GH88081), (#GH89496), (#GH90669) and (#GH91633).
+- Fix a crash when SourceLocExpr instantiated in a dependent context. 
(GH80210).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index f2bf667636dc9..f1f7d49cc6c63 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4786,8 +4786,6 @@ class SourceLocExpr final : public Expr {
 
   static bool MayBeDependent(SourceLocIdentKind Kind) {
 switch (Kind) {
-case SourceLocIdentKind::Function:
-case SourceLocIdentKind::FuncSig:
 case SourceLocIdentKind::SourceLocStruct:
   return true;
 default:
diff --git a/clang/test/CodeGenCXX/PR80210.cpp 
b/clang/test/CodeGenCXX/PR80210.cpp
new file mode 100644
index 0..fdd3beb99209e
--- /dev/null
+++ b/clang/test/CodeGenCXX/PR80210.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o /dev/null -verify -triple 
%itanium_abi_triple
+// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o /dev/null -verify -triple 
%ms_abi_triple
+
+// expected-no-diagnostics
+
+struct BasicPersistent;
+template  BasicPersistent &&__declval(int);
+template  auto declval() -> decltype(__declval<_Tp>(0));
+template  _Tp forward;
+template 
+auto construct_at(_Tp *, _Args...) -> decltype(new _Tp(declval<_Args>()...)) 
{return 0;}
+template  struct allocator;
+template  struct allocator_traits;
+template  struct allocator_traits> {
+  using pointer = _Tp *;
+  template 
+  static void construct(_Up __p, _Args...) {
+construct_at(__p, forward<_Args>...);
+  }
+};
+struct __alloc_traits : allocator_traits> {
+} push_back___x;
+__alloc_traits::pointer _M_impl_0;
+template  void emplace_back(_Args...) {
+  __alloc_traits::construct(_M_impl_0, forward<_Args>...);
+}
+struct SourceLocation {
+  static SourceLocation Current(const char * = __builtin_FUNCTION());
+};
+struct BasicPersistent {
+  BasicPersistent(BasicPersistent &&,
+  SourceLocation = SourceLocation::Current());
+};
+void CFXJSE_EngineAddObjectToUpArray() { emplace_back(push_back___x); }

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


[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-13 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> Needs changes as discussed.



> Needs changes as discussed.

I am really appreciate for your guidance and I will check in the weekend.

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


[clang] [clang] SourceLocIdentKind::Function should not be dependent (PR #94942)

2024-06-12 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> SourceLocation needs to be dependent because we want to make the name of the 
> function and any template parameter refers to the instantiated function 
> rather than that of the function template. This was changed in #78436
> 
> The issue is that SourceLocation then is a dependent expression that does not 
> depend on any parameters and its never re-transformed (hence the crash).
> 
> I have so far been unable to find a solution. I wonder if we should attach 
> the template parameters to the source location expression, but that seems a 
> bit involved.

I tested this patch locally with the code from 
https://github.com/llvm/llvm-project/issues/78128 and it works well. I doubt 
whether we need to make `SourceLocation` dependent when `Kind` is 
`SourceLocIdentKind::Function`. I don't come up with a testcase that make this 
patch failed or crash.

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


[clang] [StructuralEquivalence] improve NTTP and CXXDependentScopeMemberExpr comparison (PR #95190)

2024-06-12 Thread Qizhi Hu via cfe-commits

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


[clang] [StructuralEquivalence] improve NTTP and CXXDependentScopeMemberExpr comparison (PR #95190)

2024-06-11 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/95190

>From ba081d51a0cc803188760eec2847bfc73d2192b8 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Wed, 12 Jun 2024 09:47:16 +0800
Subject: [PATCH] [StructuralEquivalence] improve NTTP and
 CXXDependentScopeMemberExpr comparison

---
 clang/lib/AST/ASTStructuralEquivalence.cpp| 14 -
 .../AST/StructuralEquivalenceTest.cpp | 57 ++-
 2 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index d56bf21b459e0..37555c324282f 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -348,6 +348,15 @@ class StmtComparer {
 return true;
   }
 
+  bool IsStmtEquivalent(const CXXDependentScopeMemberExpr *E1,
+const CXXDependentScopeMemberExpr *E2) {
+if (!IsStructurallyEquivalent(Context, E1->getMember(), E2->getMember())) {
+  return false;
+}
+return IsStructurallyEquivalent(Context, E1->getBaseType(),
+E2->getBaseType());
+  }
+
   bool IsStmtEquivalent(const UnaryExprOrTypeTraitExpr *E1,
 const UnaryExprOrTypeTraitExpr *E2) {
 if (E1->getKind() != E2->getKind())
@@ -1997,7 +2006,10 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
 }
 return false;
   }
-
+  if (!Context.IgnoreTemplateParmDepth && D1->getDepth() != D2->getDepth())
+return false;
+  if (D1->getIndex() != D2->getIndex())
+return false;
   // Check types.
   if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
 if (Context.Complain) {
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp 
b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 91dd717d7b25e..952c83be0cb64 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1877,6 +1877,34 @@ TEST_F(StructuralEquivalenceCacheTest, 
VarDeclWithDifferentStorageClassNoEq) {
   EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
 }
 
+TEST_F(StructuralEquivalenceCacheTest,
+   NonTypeTemplateParmWithDifferentPositionNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  template
+  struct A {
+template
+void foo() {}
+  };
+  )",
+  R"(
+  template
+  struct A {
+template
+void foo() {}
+  };
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto NTTP = findDeclPair(
+  TU, nonTypeTemplateParmDecl(hasName("T")));
+  EXPECT_FALSE(Ctx.IsEquivalent(NTTP.first, NTTP.second));
+}
+
 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
   auto TU = makeTuDecls(
   R"(
@@ -2441,8 +2469,7 @@ TEST_F(StructuralEquivalenceStmtTest, 
NonTypeTemplateParm) {
   void foo(A);
   )",
   Lang_CXX11);
-  // FIXME: These should not match,
-  EXPECT_TRUE(testStructuralMatch(t));
+  EXPECT_FALSE(testStructuralMatch(t));
 }
 
 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) {
@@ -2595,5 +2622,31 @@ TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceCacheTest, CXXDependentScopeMemberExprNoEq) {
+  auto S = makeStmts(
+  R"(
+  template 
+  void foo() {
+(void)T().x;
+  }
+  struct A { int x; };
+  void bar() {
+foo();
+  }
+  )",
+  R"(
+  template 
+  void foo() {
+(void)T().y;
+  }
+  struct A { int y; };
+  void bar() {
+foo();
+  }
+  )",
+  Lang_CXX11, cxxDependentScopeMemberExpr());
+  EXPECT_FALSE(testStructuralMatch(S));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang

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


[clang] [StructuralEquivalence] improve NTTP and CXXDependentScopeMemberExpr comparison (PR #95190)

2024-06-11 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/95190

>From 157f664408062da41f4d82d20ddc06e0e563fe31 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Wed, 12 Jun 2024 09:47:16 +0800
Subject: [PATCH] [StructuralEquivalence] improve NTTP and
 CXXDependentScopeMemberExpr comparison

---
 clang/lib/AST/ASTStructuralEquivalence.cpp| 14 +-
 .../AST/StructuralEquivalenceTest.cpp | 49 ++-
 2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index d56bf21b459e0..37555c324282f 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -348,6 +348,15 @@ class StmtComparer {
 return true;
   }
 
+  bool IsStmtEquivalent(const CXXDependentScopeMemberExpr *E1,
+const CXXDependentScopeMemberExpr *E2) {
+if (!IsStructurallyEquivalent(Context, E1->getMember(), E2->getMember())) {
+  return false;
+}
+return IsStructurallyEquivalent(Context, E1->getBaseType(),
+E2->getBaseType());
+  }
+
   bool IsStmtEquivalent(const UnaryExprOrTypeTraitExpr *E1,
 const UnaryExprOrTypeTraitExpr *E2) {
 if (E1->getKind() != E2->getKind())
@@ -1997,7 +2006,10 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
 }
 return false;
   }
-
+  if (!Context.IgnoreTemplateParmDepth && D1->getDepth() != D2->getDepth())
+return false;
+  if (D1->getIndex() != D2->getIndex())
+return false;
   // Check types.
   if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
 if (Context.Complain) {
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp 
b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 91dd717d7b25e..cea1ce87a7eb9 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1877,6 +1877,34 @@ TEST_F(StructuralEquivalenceCacheTest, 
VarDeclWithDifferentStorageClassNoEq) {
   EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
 }
 
+TEST_F(StructuralEquivalenceCacheTest,
+   NonTypeTemplateParmWithDifferentPositionNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  template
+  struct A {
+template
+void foo() {}
+  };
+  )",
+  R"(
+  template
+  struct A {
+template
+void foo() {}
+  };
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto NTTP = findDeclPair(
+  TU, nonTypeTemplateParmDecl(hasName("T")));
+  EXPECT_FALSE(Ctx.IsEquivalent(NTTP.first, NTTP.second));
+}
+
 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
   auto TU = makeTuDecls(
   R"(
@@ -2441,8 +2469,7 @@ TEST_F(StructuralEquivalenceStmtTest, 
NonTypeTemplateParm) {
   void foo(A);
   )",
   Lang_CXX11);
-  // FIXME: These should not match,
-  EXPECT_TRUE(testStructuralMatch(t));
+  EXPECT_FALSE(testStructuralMatch(t));
 }
 
 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) {
@@ -2595,5 +2622,23 @@ TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceCacheTest, CXXDependentScopeMemberExprNoEq) {
+  auto S = makeStmts(
+  R"(
+  template 
+  void foo() {
+T().x;
+  }
+  )",
+  R"(
+  template 
+  void foo() {
+T().y;
+  }
+  )",
+  Lang_CXX11, cxxDependentScopeMemberExpr());
+  EXPECT_FALSE(testStructuralMatch(S));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang

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


[clang] [StructuralEquivalence] improve NTTP and CXXDependentScopeMemberExpr comparison (PR #95190)

2024-06-11 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky created 
https://github.com/llvm/llvm-project/pull/95190

improve `ASTStructuralEquivalenceTest`:

1. compare the depth and index of NTTP
2. provide comparison of `CXXDependentScopeMemberExpr` to `StmtCompare`.

>From 644c6e8499285e5b3ab17193ec63eed051dae583 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Wed, 12 Jun 2024 09:47:16 +0800
Subject: [PATCH] [StructuralEquivalence] improve NTTP and
 CXXDependentScopeMemberExpr comparison

---
 clang/lib/AST/ASTStructuralEquivalence.cpp| 14 -
 .../AST/StructuralEquivalenceTest.cpp | 52 ++-
 2 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index d56bf21b459e0..37555c324282f 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -348,6 +348,15 @@ class StmtComparer {
 return true;
   }
 
+  bool IsStmtEquivalent(const CXXDependentScopeMemberExpr *E1,
+const CXXDependentScopeMemberExpr *E2) {
+if (!IsStructurallyEquivalent(Context, E1->getMember(), E2->getMember())) {
+  return false;
+}
+return IsStructurallyEquivalent(Context, E1->getBaseType(),
+E2->getBaseType());
+  }
+
   bool IsStmtEquivalent(const UnaryExprOrTypeTraitExpr *E1,
 const UnaryExprOrTypeTraitExpr *E2) {
 if (E1->getKind() != E2->getKind())
@@ -1997,7 +2006,10 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
 }
 return false;
   }
-
+  if (!Context.IgnoreTemplateParmDepth && D1->getDepth() != D2->getDepth())
+return false;
+  if (D1->getIndex() != D2->getIndex())
+return false;
   // Check types.
   if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
 if (Context.Complain) {
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp 
b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 91dd717d7b25e..55b2580bfce3b 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1877,6 +1877,34 @@ TEST_F(StructuralEquivalenceCacheTest, 
VarDeclWithDifferentStorageClassNoEq) {
   EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
 }
 
+TEST_F(StructuralEquivalenceCacheTest,
+   NonTypeTemplateParmWithDifferentPositionNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  template
+  struct A {
+template
+void foo() {}
+  };
+  )",
+  R"(
+  template
+  struct A {
+template
+void foo() {}
+  };
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto NTTP = findDeclPair(
+  TU, nonTypeTemplateParmDecl(hasName("T")));
+  EXPECT_FALSE(Ctx.IsEquivalent(NTTP.first, NTTP.second));
+}
+
 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
   auto TU = makeTuDecls(
   R"(
@@ -2441,8 +2469,7 @@ TEST_F(StructuralEquivalenceStmtTest, 
NonTypeTemplateParm) {
   void foo(A);
   )",
   Lang_CXX11);
-  // FIXME: These should not match,
-  EXPECT_TRUE(testStructuralMatch(t));
+  EXPECT_FALSE(testStructuralMatch(t));
 }
 
 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) {
@@ -2595,5 +2622,26 @@ TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+const internal::VariadicDynCastAllOfMatcher
+cxxDependentScopeMemberExpr;
+
+TEST_F(StructuralEquivalenceCacheTest, CXXDependentScopeMemberExprNoEq) {
+  auto S = makeStmts(
+  R"(
+  template 
+  void foo() {
+T().x;
+  }
+  )",
+  R"(
+  template 
+  void foo() {
+T().y;
+  }
+  )",
+  Lang_CXX11, cxxDependentScopeMemberExpr());
+  EXPECT_FALSE(testStructuralMatch(S));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang

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


[clang] [clang] SourceLocIdentKind::Function should not be dependent (PR #94942)

2024-06-10 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> because we want to make the name of the function and any template parameter
refers to the instantiated function rather than that of the function template.

Does that mean we should transform the `SourceLocExpr` into a certain function 
name when instantiating  if it is `__builtin_FUNCTION`? 

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


[clang] [clang] SourceLocIdentKind::Function should not be dependent (PR #94942)

2024-06-10 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky created 
https://github.com/llvm/llvm-project/pull/94942

Consider the testcase, return type of `construct_at` is
```cpp
DecltypeType 0x5570d8c0 'decltype(new struct BasicPersistent(declval()))' sugar dependent
|-CXXNewExpr 0x5570d880 'struct BasicPersistent *' Function 0x5570ace0 
'operator new' 'void *(unsigned long)'
| `-CXXConstructExpr 0x5570d848 'struct BasicPersistent' 'void 
(BasicPersistent &&, SourceLocation)'
|   |-CallExpr 0x5570aae8 'BasicPersistent':'struct BasicPersistent' xvalue
|   | `-ImplicitCastExpr 0x5570aad0 'auto (*)(void) -> 
decltype(__declval(0))' 
|   |   `-DeclRefExpr 0x5570aa18 'auto (void) -> decltype(__declval(0))' lvalue Function 0x5570a908 'declval' 'auto (void) -> 
decltype(__declval(0))' (FunctionTemplate 0x556d0548 
'declval') non_odr_use_unevaluated
|   `-CXXDefaultArgExpr 0x5570d820 'SourceLocation':'struct SourceLocation' 
has rewritten init
| `-CallExpr 0x5570d7b0 'SourceLocation':'struct SourceLocation'
|   |-ImplicitCastExpr 0x5570d798 'SourceLocation (*)(const char *)' 

|   | `-DeclRefExpr 0x556fe5c8 'SourceLocation (const char *)' lvalue 
CXXMethod 0x556fdb28 'Current' 'SourceLocation (const char *)'
|   |   `-NestedNameSpecifier TypeSpec 'struct SourceLocation'
|   `-CXXDefaultArgExpr 0x5570d7f8 'const char *' has rewritten init
| `-SourceLocExpr 0x5570d7d8 'const char *'
`-PointerType 0x55704800 'struct BasicPersistent *'
  `-SubstTemplateTypeParmType 0x557047d0 'struct BasicPersistent' sugar 
typename depth 0 index 0 _Tp
|-FunctionTemplate 0x556ee048 'construct_at'
`-RecordType 0x556cfd10 'struct BasicPersistent'
  `-CXXRecord 0x556fdc98 'BasicPersistent'
```
when in the process of instantiation. This type is dependent due to the 
dependency of `SourceLocExpr` which leads to the crash(only crash in codegen 
stage and `clang-check -ast-dump` is OK). `SourceLocExpr` is created in a 
dependent context when transforming the return type of `construct_at` because 
its context(`Sema.CurContext`) is a dependent `FunctionDecl`. But 
`SourceLocExpr` should not be dependent when we finish the transformation.  
Removing `SourceLocIdentKind::Function` makes `SourceLocExpr` independent.
attempt to fix https://github.com/llvm/llvm-project/issues/80210

>From 8ad1b50f267b24693189e3a401d5970308a09f83 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Mon, 10 Jun 2024 16:53:54 +0800
Subject: [PATCH] [clang] SourceLocIdentKind::Function should not be dependent

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/include/clang/AST/Expr.h|  1 -
 clang/test/CodeGenCXX/PR80210.cpp | 34 +++
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenCXX/PR80210.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cf1ba02cbc4b2..efe78139de6fa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -846,6 +846,7 @@ Bug Fixes to C++ Support
 - Fix a crash caused by improper use of ``__array_extent``. (#GH80474)
 - Fixed several bugs in capturing variables within unevaluated contexts. 
(#GH63845), (#GH67260), (#GH69307),
   (#GH88081), (#GH89496), (#GH90669) and (#GH91633).
+- Fix a crash when SourceLocExpr instantiated in a dependent context. 
(GH80210).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index f2bf667636dc9..92bd7940bdba9 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4786,7 +4786,6 @@ class SourceLocExpr final : public Expr {
 
   static bool MayBeDependent(SourceLocIdentKind Kind) {
 switch (Kind) {
-case SourceLocIdentKind::Function:
 case SourceLocIdentKind::FuncSig:
 case SourceLocIdentKind::SourceLocStruct:
   return true;
diff --git a/clang/test/CodeGenCXX/PR80210.cpp 
b/clang/test/CodeGenCXX/PR80210.cpp
new file mode 100644
index 0..fdd3beb99209e
--- /dev/null
+++ b/clang/test/CodeGenCXX/PR80210.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o /dev/null -verify -triple 
%itanium_abi_triple
+// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o /dev/null -verify -triple 
%ms_abi_triple
+
+// expected-no-diagnostics
+
+struct BasicPersistent;
+template  BasicPersistent &&__declval(int);
+template  auto declval() -> decltype(__declval<_Tp>(0));
+template  _Tp forward;
+template 
+auto construct_at(_Tp *, _Args...) -> decltype(new _Tp(declval<_Args>()...)) 
{return 0;}
+template  struct allocator;
+template  struct allocator_traits;
+template  struct allocator_traits> {
+  using pointer = _Tp *;
+  template 
+  static void construct(_Up __p, _Args...) {
+construct_at(__p, forward<_Args>...);
+  }
+};
+struct __alloc_traits : allocator_traits> {
+} push_back___x;
+__alloc_traits::pointer _M_impl_0;
+template  void 

[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-07 Thread Qizhi Hu via cfe-commits

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


[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-07 Thread Qizhi Hu via cfe-commits




jcsxky wrote:

crash on trunk assertion.

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


[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-07 Thread Qizhi Hu via cfe-commits

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


[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-07 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94725

>From a1754c56a3293cd6529244f9a0f7486f4912e18d Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/Sema/TreeTransform.h| 18 +
 .../SemaCXX/many-template-parameter-lists.cpp |  6 +++---
 .../PR12884_original_no_crash.cpp | 20 +++
 clang/test/SemaTemplate/PR91677.cpp   | 14 +
 clang/test/SemaTemplate/instantiate-scope.cpp |  8 
 .../SemaTemplate/typename-specifier-3.cpp |  7 ---
 7 files changed, 64 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR12884_original_no_crash.cpp
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b9c9070fcb22f..e775bd6494fc0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -846,6 +846,7 @@ Bug Fixes to C++ Support
 - Fix a crash caused by improper use of ``__array_extent``. (#GH80474)
 - Fixed several bugs in capturing variables within unevaluated contexts. 
(#GH63845), (#GH67260), (#GH69307),
   (#GH88081), (#GH89496), (#GH90669) and (#GH91633).
+- Clang now transforms qualifier of template name. (#91677).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 3bfda09d5f80f..2fea4d9947870 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,24 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (getDerived().AlwaysRebuild() ||
+  QualifierLoc != TransformedQualifierLoc) {
+SS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+SS, SourceLocation(), *Template->getIdentifier(), NameLoc,
+ObjectType, FirstQualifierInScope, 
/*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..b5d954986dd4f 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{dependent nested name specifier 
'A::B::C::D::template E::' for friend class declaration is not 
supported; turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR12884_original_no_crash.cpp 
b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
new file mode 100644
index 0..f2b6f6e28c2f9
--- /dev/null
+++ b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+namespace PR12884_original {
+  template  struct A {
+struct B {
+  template  struct X {};
+  typedef int arg;
+};
+struct C {
+  typedef B::X x; // expected-error{{typename specifier 
refers to non-type member 'arg' in 'PR12884_original::A::B'}}
+};
+  };
+
+  template <> struct A::B {
+template  struct X {};
+static const int arg = 0; // expected-note{{referenced member 'arg' is 
declared here}}
+  };
+
+  A::C::x a; // expected-note{{in instantiation of member class 
'PR12884_original::A::C' requested here}}
+}
diff --git 

[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-07 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94725

>From 2977f65d503c2a96247705ce50157870aaefa003 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/Sema/TreeTransform.h| 18 +
 .../SemaCXX/many-template-parameter-lists.cpp |  6 +++---
 .../PR12884_original_no_crash.cpp | 20 +++
 clang/test/SemaTemplate/PR91677.cpp   | 14 +
 clang/test/SemaTemplate/instantiate-scope.cpp |  8 
 .../SemaTemplate/typename-specifier-3.cpp |  7 ---
 7 files changed, 64 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR12884_original_no_crash.cpp
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b9c9070fcb22f..e775bd6494fc0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -846,6 +846,7 @@ Bug Fixes to C++ Support
 - Fix a crash caused by improper use of ``__array_extent``. (#GH80474)
 - Fixed several bugs in capturing variables within unevaluated contexts. 
(#GH63845), (#GH67260), (#GH69307),
   (#GH88081), (#GH89496), (#GH90669) and (#GH91633).
+- Clang now transforms qualifier of template name. (#91677).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 3bfda09d5f80f..2fea4d9947870 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,24 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (getDerived().AlwaysRebuild() ||
+  QualifierLoc != TransformedQualifierLoc) {
+SS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+SS, SourceLocation(), *Template->getIdentifier(), NameLoc,
+ObjectType, FirstQualifierInScope, 
/*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..b5d954986dd4f 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{dependent nested name specifier 
'A::B::C::D::template E::' for friend class declaration is not 
supported; turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR12884_original_no_crash.cpp 
b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
new file mode 100644
index 0..cfc3fc06bd4cf
--- /dev/null
+++ b/clang/test/SemaTemplate/PR12884_original_no_crash.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+namespace PR12884_original {
+  template  struct A {
+struct B {
+  template  struct X {};
+  typedef int arg;
+};
+struct C {
+  typedef B::X x; // expected-error{{typename specifier 
refers to non-type member 'arg' in 'PR12884_original::A::B'}}
+};
+  };
+
+  template <> struct A::B {
+template  struct X {};
+static const int arg = 0; // expected-note{{referenced member 'arg' is 
declared here}}
+  };
+
+  A::C::x a; // expected-note{{in instantiation of member class 
'PR12884_original::A::C' requested here}}
+}
\ No newline at end of file
diff --git 

[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-07 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94725

>From 57576620fc412015bd19a34e12be61f4b81eb655 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/lib/Sema/TreeTransform.h | 18 ++
 .../SemaCXX/many-template-parameter-lists.cpp  |  6 +++---
 clang/test/SemaTemplate/PR91677.cpp| 14 ++
 clang/test/SemaTemplate/instantiate-scope.cpp  |  8 
 .../test/SemaTemplate/typename-specifier-3.cpp |  7 ---
 5 files changed, 43 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 3bfda09d5f80f..b4d31cbbf0c7c 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,24 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (!getDerived().AlwaysRebuild() &&
+  QualifierLoc != TransformedQualifierLoc) {
+SS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+SS, SourceLocation(), *Template->getIdentifier(), NameLoc,
+ObjectType, FirstQualifierInScope, 
/*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..b5d954986dd4f 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{dependent nested name specifier 
'A::B::C::D::template E::' for friend class declaration is not 
supported; turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR91677.cpp 
b/clang/test/SemaTemplate/PR91677.cpp
new file mode 100644
index 0..cc8db60a438ea
--- /dev/null
+++ b/clang/test/SemaTemplate/PR91677.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+// expected-no-diagnostics
+
+template  struct t1 {
+  template 
+  struct t2 {};
+};
+
+template 
+t1::template t2 f1();
+
+void f2() {
+  f1();
+}
diff --git a/clang/test/SemaTemplate/instantiate-scope.cpp 
b/clang/test/SemaTemplate/instantiate-scope.cpp
index 733105674b7a4..3a1708a695ceb 100644
--- a/clang/test/SemaTemplate/instantiate-scope.cpp
+++ b/clang/test/SemaTemplate/instantiate-scope.cpp
@@ -11,10 +11,10 @@ template using A = T;
 // These definitions are OK, X...> is equivalent to X
 // so this defines the member of the primary template.
 template
-void X...>::f(int) {} // expected-error {{undeclared}}
+void X...>::f(int) {} // expected-error {{use of 
undeclared identifier 'f'}}
 
 template
-int X...>::n = 0; // expected-error {{undeclared}}
+int X...>::n = 0; // expected-error {{use of undeclared 
identifier 'f'}}
 
 struct Y {}; void f(Y);
 
@@ -25,6 +25,6 @@ void g() {
 
   // Error, substitution fails; this should not be treated as a SFINAE-able
   // condition, so we don't select X::f(...).
-  X().f(0); // expected-note {{instantiation of}}
-  X::n = 1; // expected-note {{instantiation of}}
+  X().f(0); // expected-note {{in instantiation of member function 
'X::f' requested here}}
+  X::n = 1; // expected-note {{in instantiation of static data member 
'X::n' requested here}}
 }
diff --git a/clang/test/SemaTemplate/typename-specifier-3.cpp 

[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-07 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94725

>From 6a90ef0b3947a0de2d6453856c80d8f0fd393548 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/lib/Sema/TreeTransform.h | 18 ++
 .../SemaCXX/many-template-parameter-lists.cpp  |  6 +++---
 clang/test/SemaTemplate/PR91677.cpp| 14 ++
 clang/test/SemaTemplate/instantiate-scope.cpp  | 11 ++-
 .../test/SemaTemplate/typename-specifier-3.cpp |  7 ---
 5 files changed, 45 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 3bfda09d5f80f..b4d31cbbf0c7c 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,24 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (!getDerived().AlwaysRebuild() &&
+  QualifierLoc != TransformedQualifierLoc) {
+SS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+SS, SourceLocation(), *Template->getIdentifier(), NameLoc,
+ObjectType, FirstQualifierInScope, 
/*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..b5d954986dd4f 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{dependent nested name specifier 
'A::B::C::D::template E::' for friend class declaration is not 
supported; turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR91677.cpp 
b/clang/test/SemaTemplate/PR91677.cpp
new file mode 100644
index 0..cc8db60a438ea
--- /dev/null
+++ b/clang/test/SemaTemplate/PR91677.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+// expected-no-diagnostics
+
+template  struct t1 {
+  template 
+  struct t2 {};
+};
+
+template 
+t1::template t2 f1();
+
+void f2() {
+  f1();
+}
diff --git a/clang/test/SemaTemplate/instantiate-scope.cpp 
b/clang/test/SemaTemplate/instantiate-scope.cpp
index 733105674b7a4..a8f02acd23fab 100644
--- a/clang/test/SemaTemplate/instantiate-scope.cpp
+++ b/clang/test/SemaTemplate/instantiate-scope.cpp
@@ -2,7 +2,8 @@
 
 template struct X {
   void f(int);
-  void f(...);
+  void f(...); // expected-note {{member is declared here}} \
+  expected-note {{member is declared here}}
   static int n;
 };
 
@@ -11,10 +12,10 @@ template using A = T;
 // These definitions are OK, X...> is equivalent to X
 // so this defines the member of the primary template.
 template
-void X...>::f(int) {} // expected-error {{undeclared}}
+void X...>::f(int) {} // expected-error {{use of 
undeclared identifier 'f'}}
 
 template
-int X...>::n = 0; // expected-error {{undeclared}}
+int X...>::n = 0; // expected-error {{use of undeclared 
identifier 'f'}}
 
 struct Y {}; void f(Y);
 
@@ -25,6 +26,6 @@ void g() {
 
   // Error, substitution fails; this should not be treated as a SFINAE-able
   // condition, so we don't select X::f(...).
-  X().f(0); // expected-note {{instantiation of}}
-  X::n = 1; // expected-note {{instantiation of}}
+  X().f(0); // expected-note {{in instantiation of member function 
'X::f' 

[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-07 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/94725

>From 917cd980ed6a130b9f175492638afa22a1246c5c Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp |  7 +++
 clang/lib/Sema/TreeTransform.h | 18 ++
 .../SemaCXX/many-template-parameter-lists.cpp  |  6 +++---
 clang/test/SemaTemplate/PR91677.cpp| 14 ++
 clang/test/SemaTemplate/instantiate-scope.cpp  | 15 ---
 .../test/SemaTemplate/typename-specifier-3.cpp |  7 ---
 6 files changed, 50 insertions(+), 17 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 0681520764d9a..d30a9c2a2588f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -60,10 +60,9 @@ static bool SubstQualifier(Sema , const DeclT 
*OldDecl, DeclT *NewDecl,
   !OldDecl->getLexicalDeclContext()->isDependentContext()) &&
  "non-friend with qualified name defined in dependent context");
   Sema::ContextRAII SavedContext(
-  SemaRef,
-  const_cast(NewDecl->getFriendObjectKind()
-? NewDecl->getLexicalDeclContext()
-: OldDecl->getLexicalDeclContext()));
+  SemaRef, const_cast(NewDecl->getFriendObjectKind()
+ ? NewDecl->getLexicalDeclContext()
+ : NewDecl->getDeclContext()));
 
   NestedNameSpecifierLoc NewQualifierLoc
   = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(),
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 3bfda09d5f80f..b4d31cbbf0c7c 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,24 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (!getDerived().AlwaysRebuild() &&
+  QualifierLoc != TransformedQualifierLoc) {
+SS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+SS, SourceLocation(), *Template->getIdentifier(), NameLoc,
+ObjectType, FirstQualifierInScope, 
/*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..b5d954986dd4f 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{dependent nested name specifier 
'A::B::C::D::template E::' for friend class declaration is not 
supported; turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR91677.cpp 
b/clang/test/SemaTemplate/PR91677.cpp
new file mode 100644
index 0..cc8db60a438ea
--- /dev/null
+++ b/clang/test/SemaTemplate/PR91677.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+// expected-no-diagnostics
+
+template  struct t1 {
+  template 
+  struct t2 {};
+};
+
+template 
+t1::template t2 f1();
+
+void f2() {
+  f1();
+}
diff --git a/clang/test/SemaTemplate/instantiate-scope.cpp 
b/clang/test/SemaTemplate/instantiate-scope.cpp
index 

[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-07 Thread Qizhi Hu via cfe-commits

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


[clang] [Clang][Sema] qualifier should be transformed (PR #94725)

2024-06-07 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky created 
https://github.com/llvm/llvm-project/pull/94725

None

>From 9fc6172cb3ef627eb7d4e939dff6f4504c06150a Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 7 Jun 2024 14:04:52 +0800
Subject: [PATCH] [Clang][Sema] qualifier should be transformed

---
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp |  7 +++
 clang/lib/Sema/TreeTransform.h | 18 ++
 .../SemaCXX/many-template-parameter-lists.cpp  |  6 +++---
 clang/test/SemaTemplate/PR91677.cpp| 14 ++
 clang/test/SemaTemplate/instantiate-scope.cpp  | 15 ---
 .../test/SemaTemplate/typename-specifier-3.cpp |  7 ---
 6 files changed, 50 insertions(+), 17 deletions(-)
 create mode 100644 clang/test/SemaTemplate/PR91677.cpp

diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 0681520764d9a..d30a9c2a2588f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -60,10 +60,9 @@ static bool SubstQualifier(Sema , const DeclT 
*OldDecl, DeclT *NewDecl,
   !OldDecl->getLexicalDeclContext()->isDependentContext()) &&
  "non-friend with qualified name defined in dependent context");
   Sema::ContextRAII SavedContext(
-  SemaRef,
-  const_cast(NewDecl->getFriendObjectKind()
-? NewDecl->getLexicalDeclContext()
-: OldDecl->getLexicalDeclContext()));
+  SemaRef, const_cast(NewDecl->getFriendObjectKind()
+ ? NewDecl->getLexicalDeclContext()
+ : NewDecl->getDeclContext()));
 
   NestedNameSpecifierLoc NewQualifierLoc
   = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(),
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 3bfda09d5f80f..b4d31cbbf0c7c 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4568,6 +4568,24 @@ 
TreeTransform::TransformTemplateName(CXXScopeSpec ,
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
 assert(Template && "qualified template name must refer to a template");
+if (QTN->getQualifier()) {
+  CXXScopeSpec QualifierSS;
+  QualifierSS.MakeTrivial(getSema().getASTContext(), QTN->getQualifier(),
+  NameLoc);
+  NestedNameSpecifierLoc QualifierLoc =
+  QualifierSS.getWithLocInContext(getSema().getASTContext());
+  NestedNameSpecifierLoc TransformedQualifierLoc =
+  getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+  if (!TransformedQualifierLoc)
+return Name;
+  if (!getDerived().AlwaysRebuild() &&
+  QualifierLoc != TransformedQualifierLoc) {
+SS.Adopt(TransformedQualifierLoc);
+return getDerived().RebuildTemplateName(
+SS, SourceLocation(), *Template->getIdentifier(), NameLoc,
+ObjectType, FirstQualifierInScope, 
/*AllowInjectedClassName=*/true);
+  }
+}
 
 TemplateDecl *TransTemplate
   = cast_or_null(getDerived().TransformDecl(NameLoc,
diff --git a/clang/test/SemaCXX/many-template-parameter-lists.cpp 
b/clang/test/SemaCXX/many-template-parameter-lists.cpp
index f98005c7e6fb5..b5d954986dd4f 100644
--- a/clang/test/SemaCXX/many-template-parameter-lists.cpp
+++ b/clang/test/SemaCXX/many-template-parameter-lists.cpp
@@ -5,7 +5,7 @@
 template 
 struct X {
   template 
-  struct A { // expected-note {{not-yet-instantiated member is declared here}}
+  struct A {
 template 
 struct B {
   template 
@@ -28,9 +28,9 @@ struct X {
   template 
   template 
   template 
-  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{not supported}} expected-error {{no 
member 'A' in 'X'; it has not yet been instantiated}}
+  friend void A::template B::template C::template D::template 
E::operator+=(Z); // expected-warning {{dependent nested name specifier 
'A::B::C::D::template E::' for friend class declaration is not 
supported; turning off access control for 'X'}}
 };
 
 void test() {
-  X::A::B::C::D::E() += 1.0; // expected-note 
{{in instantiation of template class 'X' requested here}}
+  X::A::B::C::D::E() += 1.0;
 }
diff --git a/clang/test/SemaTemplate/PR91677.cpp 
b/clang/test/SemaTemplate/PR91677.cpp
new file mode 100644
index 0..cc8db60a438ea
--- /dev/null
+++ b/clang/test/SemaTemplate/PR91677.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+// expected-no-diagnostics
+
+template  struct t1 {
+  template 
+  struct t2 {};
+};
+
+template 
+t1::template t2 f1();
+
+void f2() {
+  f1();
+}
diff --git a/clang/test/SemaTemplate/instantiate-scope.cpp 
b/clang/test/SemaTemplate/instantiate-scope.cpp
index 

[clang] [clang][ASTImport] fix issue on anonymous enum import (PR #93923)

2024-06-04 Thread Qizhi Hu via cfe-commits

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


[clang] [libcxx] [Clang] Implement resolution for CWG1835 (PR #92957)

2024-06-04 Thread Qizhi Hu via cfe-commits


@@ -1442,19 +1442,27 @@ SourceLocation 
CXXUnresolvedConstructExpr::getBeginLoc() const {
 CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
 const ASTContext , Expr *Base, QualType BaseType, bool IsArrow,
 SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
-SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
+SourceLocation TemplateKWLoc, ArrayRef UnqualifiedLookups,
 DeclarationNameInfo MemberNameInfo,
 const TemplateArgumentListInfo *TemplateArgs)
 : Expr(CXXDependentScopeMemberExprClass, Ctx.DependentTy, VK_LValue,
OK_Ordinary),
-  Base(Base), BaseType(BaseType), QualifierLoc(QualifierLoc),
+  Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc),

jcsxky wrote:

There is a warning here. `field 'OperatorLoc' will be initialized after field 
'MemberNameInfo'`

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


[clang] [clang][ASTImport] fix issue on anonymous enum import (PR #93923)

2024-06-03 Thread Qizhi Hu via cfe-commits


@@ -9674,6 +9674,40 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
ImportInstantiatedFromMember) {
   EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember());
 }
 
+AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, ConstName) {
+  for (EnumConstantDecl *D : Node.enumerators())
+if (D->getName() == ConstName)
+  return true;
+  return false;
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
+  const char *ToCode =
+  R"(
+  struct A {
+enum { E1, E2} x;
+enum { E3, E4} y;
+  };
+  )";
+  Decl *ToTu = getToTuDecl(ToCode, Lang_CXX11);
+  auto *ToE = FirstDeclMatcher().match(
+  ToTu, enumDecl(hasEnumConstName("E1")));

jcsxky wrote:

Import test on the other enum has been added to make this test completely.

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


[clang] [clang][ASTImport] fix issue on anonymous enum import (PR #93923)

2024-06-03 Thread Qizhi Hu via cfe-commits


@@ -9674,6 +9674,40 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
ImportInstantiatedFromMember) {
   EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember());
 }
 
+AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, ConstName) {
+  for (EnumConstantDecl *D : Node.enumerators())
+if (D->getName() == ConstName)
+  return true;
+  return false;
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
+  const char *ToCode =
+  R"(
+  struct A {
+enum { E1, E2} x;
+enum { E3, E4} y;
+  };
+  )";
+  Decl *ToTu = getToTuDecl(ToCode, Lang_CXX11);
+  auto *ToE = FirstDeclMatcher().match(
+  ToTu, enumDecl(hasEnumConstName("E1")));
+  const char *Code =
+  R"(
+  struct A {
+enum { E1, E2} x;
+enum { E3, E4} y;
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromE = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E1")));
+  auto *ImportedE = Import(FromE, Lang_CXX11);
+  ASSERT_TRUE(ImportedE);
+  EXPECT_EQ(ImportedE, ToE);
+  EXPECT_FALSE(ImportedE->enumerators().empty());

jcsxky wrote:

Updated.

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


[clang] [clang][ASTImport] fix issue on anonymous enum import (PR #93923)

2024-06-03 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/93923

>From 7e602ae8d3c7ca0c3218d8ce9106510c43b6295b Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 31 May 2024 13:12:41 +0800
Subject: [PATCH 1/2] [clang][ASTImport] fix issue on anonymous enum import

---
 clang/lib/AST/ASTImporter.cpp   |  2 +-
 clang/unittests/AST/ASTImporterTest.cpp | 21 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index cab5ee6047956..3b9080e09b331 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -2929,7 +2929,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
 
   // We may already have an enum of the same name; try to find and match it.
   EnumDecl *PrevDecl = nullptr;
-  if (!DC->isFunctionOrMethod() && SearchName) {
+  if (!DC->isFunctionOrMethod()) {
 SmallVector ConflictingDecls;
 auto FoundDecls =
 Importer.findDeclsInToCtx(DC, SearchName);
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 3dc1c336365d1..4cee0b75653a5 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -9674,6 +9674,27 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
ImportInstantiatedFromMember) {
   EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
+  const char *ToCode =
+  R"(
+  struct A {
+enum { E1,E2} x;
+  };
+  )";
+  (void)getToTuDecl(ToCode, Lang_CXX11);
+  const char *Code =
+  R"(
+  struct A {
+enum { E1,E2} x;
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromE = FirstDeclMatcher().match(FromTU, enumDecl());
+  auto *ToE = Import(FromE, Lang_CXX11);
+  ASSERT_TRUE(ToE);
+  EXPECT_FALSE(ToE->enumerators().empty());
+}
+
 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
  DefaultTestValuesForRunOptions);
 

>From d8c1d25b026c0377bd5d84644fb13cd072f9694c Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Sat, 1 Jun 2024 00:52:01 +0800
Subject: [PATCH 2/2] update testcase

---
 clang/unittests/AST/ASTImporterTest.cpp | 33 +++--
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 4cee0b75653a5..92f9bae6cb064 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -9674,25 +9674,44 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
ImportInstantiatedFromMember) {
   EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember());
 }
 
+AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, ConstName) {
+  for (EnumConstantDecl *D : Node.enumerators())
+if (D->getName() == ConstName)
+  return true;
+  return false;
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
   const char *ToCode =
   R"(
   struct A {
-enum { E1,E2} x;
+enum { E1, E2} x;
+enum { E3, E4} y;
   };
   )";
-  (void)getToTuDecl(ToCode, Lang_CXX11);
+  Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11);
+  auto *ToE1 = FirstDeclMatcher().match(
+  ToTU, enumDecl(hasEnumConstName("E1")));
+  auto *ToE3 = FirstDeclMatcher().match(
+  ToTU, enumDecl(hasEnumConstName("E3")));
   const char *Code =
   R"(
   struct A {
-enum { E1,E2} x;
+enum { E1, E2} x;
+enum { E3, E4} y;
   };
   )";
   Decl *FromTU = getTuDecl(Code, Lang_CXX11);
-  auto *FromE = FirstDeclMatcher().match(FromTU, enumDecl());
-  auto *ToE = Import(FromE, Lang_CXX11);
-  ASSERT_TRUE(ToE);
-  EXPECT_FALSE(ToE->enumerators().empty());
+  auto *FromE1 = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E1")));
+  auto *ImportedE1 = Import(FromE1, Lang_CXX11);
+  ASSERT_TRUE(ImportedE1);
+  EXPECT_EQ(ImportedE1, ToE1);
+  auto *FromE3 = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E3")));
+  auto *ImportedE3 = Import(FromE3, Lang_CXX11);
+  ASSERT_TRUE(ImportedE3);
+  EXPECT_EQ(ImportedE3, ToE3);
 }
 
 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,

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


[clang] [clang][ASTImport] fix issue on anonymous enum import (PR #93923)

2024-05-31 Thread Qizhi Hu via cfe-commits


@@ -9674,6 +9674,27 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
ImportInstantiatedFromMember) {
   EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
+  const char *ToCode =
+  R"(
+  struct A {
+enum { E1,E2} x;
+  };
+  )";
+  (void)getToTuDecl(ToCode, Lang_CXX11);
+  const char *Code =
+  R"(
+  struct A {
+enum { E1,E2} x;
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromE = FirstDeclMatcher().match(FromTU, enumDecl());
+  auto *ToE = Import(FromE, Lang_CXX11);
+  ASSERT_TRUE(ToE);
+  EXPECT_FALSE(ToE->enumerators().empty());

jcsxky wrote:

Done.

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


[clang] [clang][ASTImport] fix issue on anonymous enum import (PR #93923)

2024-05-31 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> Does this work on the following code?
> 
> ```
>  struct A {
> enum { E1,E2 } x;
> enum { E3,E4 } y;
>   };
> ```

I have updated testcase according to your suggestion to demonstrate this 
solution works correctly on the testcase above.

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


[clang] [clang][ASTImport] fix issue on anonymous enum import (PR #93923)

2024-05-31 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/93923

>From 7e602ae8d3c7ca0c3218d8ce9106510c43b6295b Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 31 May 2024 13:12:41 +0800
Subject: [PATCH 1/2] [clang][ASTImport] fix issue on anonymous enum import

---
 clang/lib/AST/ASTImporter.cpp   |  2 +-
 clang/unittests/AST/ASTImporterTest.cpp | 21 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index cab5ee6047956..3b9080e09b331 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -2929,7 +2929,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
 
   // We may already have an enum of the same name; try to find and match it.
   EnumDecl *PrevDecl = nullptr;
-  if (!DC->isFunctionOrMethod() && SearchName) {
+  if (!DC->isFunctionOrMethod()) {
 SmallVector ConflictingDecls;
 auto FoundDecls =
 Importer.findDeclsInToCtx(DC, SearchName);
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 3dc1c336365d1..4cee0b75653a5 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -9674,6 +9674,27 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
ImportInstantiatedFromMember) {
   EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
+  const char *ToCode =
+  R"(
+  struct A {
+enum { E1,E2} x;
+  };
+  )";
+  (void)getToTuDecl(ToCode, Lang_CXX11);
+  const char *Code =
+  R"(
+  struct A {
+enum { E1,E2} x;
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromE = FirstDeclMatcher().match(FromTU, enumDecl());
+  auto *ToE = Import(FromE, Lang_CXX11);
+  ASSERT_TRUE(ToE);
+  EXPECT_FALSE(ToE->enumerators().empty());
+}
+
 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
  DefaultTestValuesForRunOptions);
 

>From a32f4f879ef4e080b192ad6a4ee1528591ce2136 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Sat, 1 Jun 2024 00:52:01 +0800
Subject: [PATCH 2/2] update testcase

---
 clang/unittests/AST/ASTImporterTest.cpp | 27 ++---
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 4cee0b75653a5..dcf30d7ec1a6f 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -9674,25 +9674,38 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
ImportInstantiatedFromMember) {
   EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember());
 }
 
+AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, ConstName) {
+  for (EnumConstantDecl *D : Node.enumerators())
+if (D->getName() == ConstName)
+  return true;
+  return false;
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
   const char *ToCode =
   R"(
   struct A {
-enum { E1,E2} x;
+enum { E1, E2} x;
+enum { E3, E4} y;
   };
   )";
-  (void)getToTuDecl(ToCode, Lang_CXX11);
+  Decl *ToTu = getToTuDecl(ToCode, Lang_CXX11);
+  auto *ToE = FirstDeclMatcher().match(
+  ToTu, enumDecl(hasEnumConstName("E1")));
   const char *Code =
   R"(
   struct A {
-enum { E1,E2} x;
+enum { E1, E2} x;
+enum { E3, E4} y;
   };
   )";
   Decl *FromTU = getTuDecl(Code, Lang_CXX11);
-  auto *FromE = FirstDeclMatcher().match(FromTU, enumDecl());
-  auto *ToE = Import(FromE, Lang_CXX11);
-  ASSERT_TRUE(ToE);
-  EXPECT_FALSE(ToE->enumerators().empty());
+  auto *FromE = FirstDeclMatcher().match(
+  FromTU, enumDecl(hasEnumConstName("E1")));
+  auto *ImportedE = Import(FromE, Lang_CXX11);
+  ASSERT_TRUE(ImportedE);
+  EXPECT_EQ(ImportedE, ToE);
+  EXPECT_FALSE(ImportedE->enumerators().empty());
 }
 
 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,

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


[clang] [clang][ASTImport] fix issue on anonymous enum import (PR #93923)

2024-05-30 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky created 
https://github.com/llvm/llvm-project/pull/93923

Don't skip searching in `ToContext` during importing `EnumDecl`. And 
`IsStructuralMatch` in `StructralEquivalence` can make sure to determine 
whether the found result is match or not.

>From 7e602ae8d3c7ca0c3218d8ce9106510c43b6295b Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Fri, 31 May 2024 13:12:41 +0800
Subject: [PATCH] [clang][ASTImport] fix issue on anonymous enum import

---
 clang/lib/AST/ASTImporter.cpp   |  2 +-
 clang/unittests/AST/ASTImporterTest.cpp | 21 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index cab5ee6047956..3b9080e09b331 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -2929,7 +2929,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
 
   // We may already have an enum of the same name; try to find and match it.
   EnumDecl *PrevDecl = nullptr;
-  if (!DC->isFunctionOrMethod() && SearchName) {
+  if (!DC->isFunctionOrMethod()) {
 SmallVector ConflictingDecls;
 auto FoundDecls =
 Importer.findDeclsInToCtx(DC, SearchName);
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 3dc1c336365d1..4cee0b75653a5 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -9674,6 +9674,27 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
ImportInstantiatedFromMember) {
   EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
+  const char *ToCode =
+  R"(
+  struct A {
+enum { E1,E2} x;
+  };
+  )";
+  (void)getToTuDecl(ToCode, Lang_CXX11);
+  const char *Code =
+  R"(
+  struct A {
+enum { E1,E2} x;
+  };
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
+  auto *FromE = FirstDeclMatcher().match(FromTU, enumDecl());
+  auto *ToE = Import(FromE, Lang_CXX11);
+  ASSERT_TRUE(ToE);
+  EXPECT_FALSE(ToE->enumerators().empty());
+}
+
 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
  DefaultTestValuesForRunOptions);
 

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


[clang] [Clang][Sema] Use correct TemplateName when transforming TemplateSpecializationType (PR #93411)

2024-05-30 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> So After we have formed a TemplateSpecializationType, we are done with the 
> NNS. We keep it around in an ElaboratedType for type sugar only, it should 
> not be needed to compile the program correctly anymore.
> 
> So I think this solution violates one important aspect of our AST design.
> 
> If we still need the NNS, we have to hold-off on building the TST until we 
> don't.

Ah, I see. Thanks for your explanation on the motivation of AST design!

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


[clang] [libcxx] [clang] Preserve Qualifiers and type sugar in TemplateNames (PR #93433)

2024-05-30 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

@mizvekov After I apply you changes in this patch, 
https://github.com/llvm/llvm-project/issues/91677 is still crash(although it 
makes sense with `-ast-dump` option). I put it below for explanation clearly:
```cpp
template  struct t1 {
  template 
  struct t2 {};
};

template 
t1::template t2 f1();

void f2() {
  f1();
}
```

The reason seems that we transform `TemplateDecl` to the original one and do 
nothing and then crash in codegen stage. For `t1::t2`, we have 
transformed qualifier(`t1`) in `TransformElaboratedType`. But, we transform 
qualifier in `TransformTemplateName` for `t2` again because of transforming 
`TransformTemplateSpecializationType`. This leads to the  transformation of the 
`TemplateDecl` as I described in the beginning.
I think we can reuse the transformed qualifier(`t1`) in 
`TransformElaboratedType` and this is what I did in 
https://github.com/llvm/llvm-project/pull/93411. Could you please take another 
look?

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


[clang] [Clang][Sema] Use correct TemplateName when transforming TemplateSpecializationType (PR #93411)

2024-05-28 Thread Qizhi Hu via cfe-commits

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


[clang] [Clang][Sema] Use correct TemplateName when transforming TemplateSpecializationType (PR #93411)

2024-05-27 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> The problem here is the loss of the qualification on the TemplateNames
> 
> This patch fixes the problem, without taking any workarounds: #93433
> 
> It also doesn't cause any change in diagnostics in 
> `clang/test/SemaTemplate/typename-specifier-3.cpp`.

I think we should report this message since `B::arg` in `A` is a NTTP.

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


[clang] [Clang][Sema] Use correct TemplateName when transforming TemplateSpecializationType (PR #93411)

2024-05-26 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/93411

>From f5f0b14945a70e3e4fd92d5e5cbdb428334fe2b8 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Sat, 25 May 2024 16:30:27 +0800
Subject: [PATCH 1/2] [Clang][Sema] Use correct TemplateName when transforming
 TemplateSpecializationType

---
 clang/lib/Sema/TreeTransform.h | 43 +-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index dee335b526991..7e8b080a347e8 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -29,8 +29,10 @@
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtOpenACC.h"
 #include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/DiagnosticParse.h"
 #include "clang/Basic/OpenMPKinds.h"
+#include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Lookup.h"
@@ -7216,7 +7218,46 @@ 
TreeTransform::TransformElaboratedType(TypeLocBuilder ,
   return QualType();
   }
 
-  QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
+  QualType NamedT;
+  if (0 && SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc && 
isa(TL.getNamedTypeLoc().getType())) {
+const TemplateSpecializationType *TST = 
TL.getNamedTypeLoc().getType()->getAs();
+TemplateSpecializationTypeLoc SpecTL =
+TL.getNamedTypeLoc().castAs();
+// TemplateArgumentListInfo NewTemplateArgs;
+// NewTemplateArgs.setLAngleLoc(SpecTL.getLAngleLoc());
+// NewTemplateArgs.setRAngleLoc(SpecTL.getRAngleLoc());
+
+// typedef TemplateArgumentLocContainerIterator<
+// TemplateSpecializationTypeLoc> ArgIterator;
+// if (getDerived().TransformTemplateArguments(ArgIterator(SpecTL, 0),
+// ArgIterator(SpecTL, 
SpecTL.getNumArgs()),
+// NewTemplateArgs))
+//   return QualType();
+
+CXXScopeSpec SS;
+SS.Adopt(QualifierLoc);
+TemplateName InstName = getDerived().RebuildTemplateName(
+SS, TL.getTemplateKeywordLoc(), 
*TST->getTemplateName().getAsTemplateDecl()->getIdentifier(), 
TL.getNamedTypeLoc().getBeginLoc(), QualType(), nullptr,
+false);
+
+if (InstName.isNull())
+  return QualType();
+
+// If it's still dependent, make a dependent specialization.
+// if (InstName.getAsDependentTemplateName())
+//   return SemaRef.Context.getDependentTemplateSpecializationType(
+//   Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
+//   Args.arguments());
+
+// Otherwise, make an elaborated type wrapping a non-dependent
+// specialization.
+// NamedT = getDerived().RebuildTemplateSpecializationType(InstName, 
TL.getNamedTypeLoc().getBeginLoc(), NewTemplateArgs);
+NamedT = TransformTemplateSpecializationType(TLB, SpecTL, InstName);
+  } else {
+NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
+
+  }
+
   if (NamedT.isNull())
 return QualType();
 

>From 3ebed0fecd90101b57082909348a60070c689d12 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Sun, 26 May 2024 19:35:17 +0800
Subject: [PATCH 2/2] [Clang][Sema] Use correct TemplateName when transforming
 TemplateSpecializationType

---
 clang/lib/Sema/TreeTransform.h| 54 ++-
 clang/test/SemaCXX/PR91677.cpp| 14 +
 .../SemaTemplate/typename-specifier-3.cpp |  7 +--
 3 files changed, 35 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR91677.cpp

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 7e8b080a347e8..6ef2eec09ec02 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -29,10 +29,8 @@
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtOpenACC.h"
 #include "clang/AST/StmtOpenMP.h"
-#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/DiagnosticParse.h"
 #include "clang/Basic/OpenMPKinds.h"
-#include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Lookup.h"
@@ -7219,48 +7217,30 @@ 
TreeTransform::TransformElaboratedType(TypeLocBuilder ,
   }
 
   QualType NamedT;
-  if (0 && SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc && 
isa(TL.getNamedTypeLoc().getType())) {
-const TemplateSpecializationType *TST = 
TL.getNamedTypeLoc().getType()->getAs();
+  if (SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc &&
+  isa(TL.getNamedTypeLoc().getType())) {
 TemplateSpecializationTypeLoc SpecTL =
 TL.getNamedTypeLoc().castAs();
-// TemplateArgumentListInfo NewTemplateArgs;
-// NewTemplateArgs.setLAngleLoc(SpecTL.getLAngleLoc());
-// NewTemplateArgs.setRAngleLoc(SpecTL.getRAngleLoc());
-
-// typedef 

[clang] [Clang][Sema] Use correct TemplateName when transforming TemplateSpecializationType (PR #93411)

2024-05-26 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/93411

>From f5f0b14945a70e3e4fd92d5e5cbdb428334fe2b8 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Sat, 25 May 2024 16:30:27 +0800
Subject: [PATCH 1/2] [Clang][Sema] Use correct TemplateName when transforming
 TemplateSpecializationType

---
 clang/lib/Sema/TreeTransform.h | 43 +-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index dee335b526991..7e8b080a347e8 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -29,8 +29,10 @@
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtOpenACC.h"
 #include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/DiagnosticParse.h"
 #include "clang/Basic/OpenMPKinds.h"
+#include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Lookup.h"
@@ -7216,7 +7218,46 @@ 
TreeTransform::TransformElaboratedType(TypeLocBuilder ,
   return QualType();
   }
 
-  QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
+  QualType NamedT;
+  if (0 && SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc && 
isa(TL.getNamedTypeLoc().getType())) {
+const TemplateSpecializationType *TST = 
TL.getNamedTypeLoc().getType()->getAs();
+TemplateSpecializationTypeLoc SpecTL =
+TL.getNamedTypeLoc().castAs();
+// TemplateArgumentListInfo NewTemplateArgs;
+// NewTemplateArgs.setLAngleLoc(SpecTL.getLAngleLoc());
+// NewTemplateArgs.setRAngleLoc(SpecTL.getRAngleLoc());
+
+// typedef TemplateArgumentLocContainerIterator<
+// TemplateSpecializationTypeLoc> ArgIterator;
+// if (getDerived().TransformTemplateArguments(ArgIterator(SpecTL, 0),
+// ArgIterator(SpecTL, 
SpecTL.getNumArgs()),
+// NewTemplateArgs))
+//   return QualType();
+
+CXXScopeSpec SS;
+SS.Adopt(QualifierLoc);
+TemplateName InstName = getDerived().RebuildTemplateName(
+SS, TL.getTemplateKeywordLoc(), 
*TST->getTemplateName().getAsTemplateDecl()->getIdentifier(), 
TL.getNamedTypeLoc().getBeginLoc(), QualType(), nullptr,
+false);
+
+if (InstName.isNull())
+  return QualType();
+
+// If it's still dependent, make a dependent specialization.
+// if (InstName.getAsDependentTemplateName())
+//   return SemaRef.Context.getDependentTemplateSpecializationType(
+//   Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
+//   Args.arguments());
+
+// Otherwise, make an elaborated type wrapping a non-dependent
+// specialization.
+// NamedT = getDerived().RebuildTemplateSpecializationType(InstName, 
TL.getNamedTypeLoc().getBeginLoc(), NewTemplateArgs);
+NamedT = TransformTemplateSpecializationType(TLB, SpecTL, InstName);
+  } else {
+NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
+
+  }
+
   if (NamedT.isNull())
 return QualType();
 

>From e60cdac25c4ea2e85894e51dfd5268544cadd27d Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Sun, 26 May 2024 19:35:17 +0800
Subject: [PATCH 2/2] [Clang][Sema] Use correct TemplateName when transforming
 TemplateSpecializationType

---
 clang/lib/Sema/TreeTransform.h| 54 ++-
 clang/test/SemaCXX/PR91677.cpp| 31 +++
 .../SemaTemplate/typename-specifier-3.cpp |  7 +--
 3 files changed, 52 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR91677.cpp

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 7e8b080a347e8..6ef2eec09ec02 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -29,10 +29,8 @@
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtOpenACC.h"
 #include "clang/AST/StmtOpenMP.h"
-#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/DiagnosticParse.h"
 #include "clang/Basic/OpenMPKinds.h"
-#include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Lookup.h"
@@ -7219,48 +7217,30 @@ 
TreeTransform::TransformElaboratedType(TypeLocBuilder ,
   }
 
   QualType NamedT;
-  if (0 && SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc && 
isa(TL.getNamedTypeLoc().getType())) {
-const TemplateSpecializationType *TST = 
TL.getNamedTypeLoc().getType()->getAs();
+  if (SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc &&
+  isa(TL.getNamedTypeLoc().getType())) {
 TemplateSpecializationTypeLoc SpecTL =
 TL.getNamedTypeLoc().castAs();
-// TemplateArgumentListInfo NewTemplateArgs;
-// NewTemplateArgs.setLAngleLoc(SpecTL.getLAngleLoc());
-// NewTemplateArgs.setRAngleLoc(SpecTL.getRAngleLoc());
-
-// typedef 

[clang] [Clang][Sema] Use correct TemplateName when transforming TemplateSpecializationType (PR #93411)

2024-05-26 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky created 
https://github.com/llvm/llvm-project/pull/93411

Consider the following testcase:
```cpp
namespace PR12884_original {
  template  struct A {
struct B { ##1
  template  struct X {};
  typedef int arg;
};
struct C {
  typedef B::X x; 
};
  };

  template <> struct A::B { ##2
template  struct X {};
static const int arg = 0;
  };

  A::C::x a;
}
```
It will crash when compiling with `clang(assertions trunk)`. The reason is that 
we lookup `X`(`B::X`) in `##1` when instantiating `typedef B::X x; ` during instantiating `A::C::x`. This is incorrect because we 
should lookup `X` in `##2` when we see the declaration `A::C::x a;`. Since 
clang parse `A::B` to an `ElaboratedType`(`typename` is not required 
while compiling with `-std=c++20`)  while `typename A::B` turns to be a 
`DependentTemplateSpecializationType`, we should rebuild the `TemplateName` 
with transformed `Qualifier`(whose type is `NestedNameSpecifier`) to make sure 
the lookup context is correct.
This patch also attempts to fix #91677 which crashes with the same reason.

>From ee56373184dff3fd721709ca07a1770957eace29 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Sat, 25 May 2024 16:30:27 +0800
Subject: [PATCH 1/2] [Clang][Sema] Use correct TemplateName when transforming
 TemplateSpecializationType

---
 clang/lib/Sema/TreeTransform.h | 43 +-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index dee335b526991..7e8b080a347e8 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -29,8 +29,10 @@
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtOpenACC.h"
 #include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/DiagnosticParse.h"
 #include "clang/Basic/OpenMPKinds.h"
+#include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Lookup.h"
@@ -7216,7 +7218,46 @@ 
TreeTransform::TransformElaboratedType(TypeLocBuilder ,
   return QualType();
   }
 
-  QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
+  QualType NamedT;
+  if (0 && SemaRef.getLangOpts().CPlusPlus20 && QualifierLoc && 
isa(TL.getNamedTypeLoc().getType())) {
+const TemplateSpecializationType *TST = 
TL.getNamedTypeLoc().getType()->getAs();
+TemplateSpecializationTypeLoc SpecTL =
+TL.getNamedTypeLoc().castAs();
+// TemplateArgumentListInfo NewTemplateArgs;
+// NewTemplateArgs.setLAngleLoc(SpecTL.getLAngleLoc());
+// NewTemplateArgs.setRAngleLoc(SpecTL.getRAngleLoc());
+
+// typedef TemplateArgumentLocContainerIterator<
+// TemplateSpecializationTypeLoc> ArgIterator;
+// if (getDerived().TransformTemplateArguments(ArgIterator(SpecTL, 0),
+// ArgIterator(SpecTL, 
SpecTL.getNumArgs()),
+// NewTemplateArgs))
+//   return QualType();
+
+CXXScopeSpec SS;
+SS.Adopt(QualifierLoc);
+TemplateName InstName = getDerived().RebuildTemplateName(
+SS, TL.getTemplateKeywordLoc(), 
*TST->getTemplateName().getAsTemplateDecl()->getIdentifier(), 
TL.getNamedTypeLoc().getBeginLoc(), QualType(), nullptr,
+false);
+
+if (InstName.isNull())
+  return QualType();
+
+// If it's still dependent, make a dependent specialization.
+// if (InstName.getAsDependentTemplateName())
+//   return SemaRef.Context.getDependentTemplateSpecializationType(
+//   Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
+//   Args.arguments());
+
+// Otherwise, make an elaborated type wrapping a non-dependent
+// specialization.
+// NamedT = getDerived().RebuildTemplateSpecializationType(InstName, 
TL.getNamedTypeLoc().getBeginLoc(), NewTemplateArgs);
+NamedT = TransformTemplateSpecializationType(TLB, SpecTL, InstName);
+  } else {
+NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
+
+  }
+
   if (NamedT.isNull())
 return QualType();
 

>From cb29d45c174f4fd267c273c4386a2010941a63ac Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Sun, 26 May 2024 19:35:17 +0800
Subject: [PATCH 2/2] [Clang][Sema] Use correct TemplateName when transforming
 TemplateSpecializationType

---
 clang/lib/Sema/TreeTransform.h| 54 ++-
 clang/test/SemaCXX/PR91677.cpp| 31 +++
 .../SemaTemplate/typename-specifier-3.cpp |  7 +--
 3 files changed, 52 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR91677.cpp

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 7e8b080a347e8..6ef2eec09ec02 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -29,10 +29,8 @@
 #include "clang/AST/StmtObjC.h"
 

[clang] [clang][ASTImporter] Fix possible crash "given incorrect InsertPos for specialization". (PR #89887)

2024-05-25 Thread Qizhi Hu via cfe-commits

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


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


[clang] [clang][ASTImporter] Fix possible crash "given incorrect InsertPos for specialization". (PR #89887)

2024-05-25 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> > Could you please show your commands which reproduced this crash? I tested 
> > locally with the following commands and it runs OK.
> > ```c++
> > clang++ -cc1 -std=c++17 -emit-pch -o test.cpp.ast test.cpp
> > clang++ -cc1 -x c++ -ast-merge test.cpp.ast  /dev/null -ast-dump
> > ```
> 
> That code is only an example, it differs not much of the real code that 
> caused the crash. But it is not enough to use this code for the problem 
> reproduction. This code can be used to get the case when the specialization 
> list is changed before the insertion, but even then no crash happens:
> 
> ```c++
> namespace N {
> template 
> int B = B + B;
> template <>
> int B<0> = 0;
> template <>
> int B<1> = 1;
> }
> int A = N::B<5>;
> ```
> 
> With clang version 18.1.6 the original crash does not occur any more. The 
> "original crash" was reproduced on specific source files of project 
> "contour". Probably I can attach the files and command, but some changes can 
> be required to make it work.

Could you please show me how to reproduce the crash in detail if possible? Then 
I can debug this issue in my spare time.

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


[clang] [clang][ASTImporter] Fix possible crash "given incorrect InsertPos for specialization". (PR #89887)

2024-05-24 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> A test is needed to make the change acceptable but I could not find an easy 
> case to provoke the situation. The problem looks to be related to his code:
> 
> ```c++
> using size_t = int;
> template class tuple;
> 
> template
> struct integral_constant
> {
> static constexpr T value = v;
> using value_type = T;
> using type = integral_constant; // using injected-class-name
> constexpr operator value_type() const noexcept { return value; }
> constexpr value_type operator()() const noexcept { return value; } // 
> since c++14
> };
> 
> using true_type = integral_constant;
> using false_type = integral_constant;
> 
> template
> struct is_same : false_type {};
>  
> template
> struct is_same : true_type {};
> 
> template< class T, class U >
> inline constexpr bool is_same_v = is_same::value;
> 
> namespace A {
>   template
>   struct __tuple_count;
> 
>   template
> inline constexpr size_t __tuple_count_v =
>   __tuple_count<_Tp, _Tuple>::value;
> 
>   template
> struct __tuple_count<_Tp, tuple<_Types...>>
> : integral_constant { };
> 
>   template
> struct __tuple_count<_Tp, tuple<_First, _Rest...>>
> : integral_constant<
>   size_t,
>   __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { };
> };
> 
> 
> size_t x = A::__tuple_count_v>;
> ```

Could you please show your commands which reproduced this crash? I tested 
locally with the following commands and it runs OK.
```cpp
clang++ -cc1 -std=c++17 -emit-pch -o test.cpp.ast test.cpp
clang++ -cc1 -x c++ -ast-merge test.cpp.ast  /dev/null -ast-dump
```

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


[clang] [Clang][AST] fix crash in mangle lambda expression (PR #78896)

2024-05-19 Thread Qizhi Hu via cfe-commits

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


[clang] [clang] visit constraint of NTTP (PR #91842)

2024-05-16 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> I don't think this is the right approach. I stepped though the example and 
> the reason we reject is because:
> 
> * We substitute a dependent `AutoType` in for the types of the template 
> parameters when they are initially built.
> * We call `getMoreSpecialized` determine whether the partial specialization 
> is more specialized than the primary.
> * We determine that neither template is at least as specialized as the other 
> via `isAtLeastAsSpecializedAs`.
> * We call `TemplateParameterListsAreEqual` per [[temp.func.order] 
> p6.2.2](http://eel.is/c++draft/temp.func.order#6.2.2) to check for template 
> parameter equivalence, and compare the two template parameters by calling 
> `MatchTemplateParameterKind`.
> * `MatchTemplateParameterKind` calls `ASTContext::getUnconstrainedType` to 
> get the unconstrained type of the template parameters per [[temp.over.link] 
> p6 sentence 2](http://eel.is/c++draft/temp.over.link#6.sentence-2). For the 
> class templates template parameter, it returns the type unchanged (a 
> _**dependent**_ `AutoType`). For the class template partial specializations 
> template parameter, it returns an unconstrained `AutoType` _**that isn't 
> dependent**_.
> * We compare the adjusted types and determine they aren't equal, so we 
> consider neither template to be more specialized than the other.
> 
> So, I think the correct fix is to propagate dependence in 
> `ASTContext::getUnconstrainedType`. I have a branch that implements this 
> [here](https://github.com/sdkrystian/llvm-project/tree/partial-spec-dependent-auto).
>  WDYT @erichkeane @cor3ntin @zyn0217?

This is really a perfect approach and it has addressed the underlying issue. 
And thanks for your explaination! 

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


[clang] [clang] visit constraint of NTTP (PR #91842)

2024-05-12 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/91842

>From 0ebdcec675c39b26b8bee1a8b07c12fae2c58523 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sat, 11 May 2024 14:04:23 +0800
Subject: [PATCH] [clang] visit constraint of NTTP

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/AST/StmtProfile.cpp |  4 
 .../temp.fct/temp.func.order/p6.cpp   |  6 +++---
 clang/test/SemaCXX/PR77377.cpp| 19 +++
 4 files changed, 27 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR77377.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7c5dcc59c7016..30d359c582d3f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -707,6 +707,7 @@ Bug Fixes to C++ Support
   initialized, rather than evaluating them as a part of the larger manifestly 
constant evaluated
   expression.
 - Fix a bug in access control checking due to dealyed checking of friend 
declaration. Fixes (#GH12361).
+- Fix a bug on template class partial specialization due to traverse of 
constraint of NTTP. Fixes (#GH77377).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 8fb8940142eb0..a23a2efa2389e 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2257,6 +2257,10 @@ void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
 const SubstNonTypeTemplateParmExpr *E) {
   // Profile exactly as the replacement expression.
   Visit(E->getReplacement());
+  if (auto *NTTP = dyn_cast(E->getParameter());
+  NTTP && NTTP->getPlaceholderTypeConstraint()) {
+Visit(NTTP->getPlaceholderTypeConstraint());
+  }
 }
 
 void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp 
b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
index 9f44878da6254..5f9719a2dc561 100644
--- a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -79,14 +79,14 @@ template struct Y2 {}; // 
expected-note {{partial
 template class U, typename... Z>
 struct Y3 { Y3()=delete; };
 template class U, typename... Z>
-struct Y3 { Y3()=delete; };
+struct Y3 { Y3()=delete; }; // expected-note {{partial 
specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}}
 template class U, typename... Z>
-struct Y3 {};
+struct Y3 {}; // expected-note {{partial specialization 
matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}}
 
 void f() {
   Y1 a;
   Y2 b; // expected-error {{ambiguous partial specializations}}
-  Y3 c;
+  Y3 c; // expected-error {{ambiguous partial 
specializations of 'Y3'}}
 }
 
 // Per [temp.func.order]p6.2.2, specifically "if the function parameters that
diff --git a/clang/test/SemaCXX/PR77377.cpp b/clang/test/SemaCXX/PR77377.cpp
new file mode 100644
index 0..ae34809c3903d
--- /dev/null
+++ b/clang/test/SemaCXX/PR77377.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+// expected-no-diagnostics
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept same_as = is_same_v;
+
+template 
+struct A {};
+
+template  auto p>
+struct A {};
+
+A<0> a;

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


[clang] [clang] visit constraint of NTTP (PR #91842)

2024-05-12 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/91842

>From 4133001711b82c93e057e1bd05476c5d052d597f Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sat, 11 May 2024 14:04:23 +0800
Subject: [PATCH] [clang] visit constraint of NTTP

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/AST/StmtProfile.cpp |  4 
 .../temp.fct/temp.func.order/p6.cpp   |  6 +++---
 clang/test/SemaCXX/PR77377.cpp| 19 +++
 4 files changed, 27 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR77377.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7c5dcc59c7016..30d359c582d3f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -707,6 +707,7 @@ Bug Fixes to C++ Support
   initialized, rather than evaluating them as a part of the larger manifestly 
constant evaluated
   expression.
 - Fix a bug in access control checking due to dealyed checking of friend 
declaration. Fixes (#GH12361).
+- Fix a bug on template class partial specialization due to traverse of 
constraint of NTTP. Fixes (#GH77377).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 8fb8940142eb0..a23a2efa2389e 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2257,6 +2257,10 @@ void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
 const SubstNonTypeTemplateParmExpr *E) {
   // Profile exactly as the replacement expression.
   Visit(E->getReplacement());
+  if (auto *NTTP = dyn_cast(E->getParameter());
+  NTTP && NTTP->getPlaceholderTypeConstraint()) {
+Visit(NTTP->getPlaceholderTypeConstraint());
+  }
 }
 
 void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp 
b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
index 9f44878da6254..5f9719a2dc561 100644
--- a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -79,14 +79,14 @@ template struct Y2 {}; // 
expected-note {{partial
 template class U, typename... Z>
 struct Y3 { Y3()=delete; };
 template class U, typename... Z>
-struct Y3 { Y3()=delete; };
+struct Y3 { Y3()=delete; }; // expected-note {{partial 
specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}}
 template class U, typename... Z>
-struct Y3 {};
+struct Y3 {}; // expected-note {{partial specialization 
matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}}
 
 void f() {
   Y1 a;
   Y2 b; // expected-error {{ambiguous partial specializations}}
-  Y3 c;
+  Y3 c; // expected-error {{ambiguous partial 
specializations of 'Y3'}}
 }
 
 // Per [temp.func.order]p6.2.2, specifically "if the function parameters that
diff --git a/clang/test/SemaCXX/PR77377.cpp b/clang/test/SemaCXX/PR77377.cpp
new file mode 100644
index 0..ae34809c3903d
--- /dev/null
+++ b/clang/test/SemaCXX/PR77377.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+// expected-no-diagnostics
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept same_as = is_same_v;
+
+template 
+struct A {};
+
+template  auto p>
+struct A {};
+
+A<0> a;

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


[clang] [clang] visit constraint of NTTP (PR #91842)

2024-05-11 Thread Qizhi Hu via cfe-commits


@@ -79,14 +79,14 @@ template struct Y2 {}; // 
expected-note {{partial
 template class U, typename... Z>
 struct Y3 { Y3()=delete; };
 template class U, typename... Z>
-struct Y3 { Y3()=delete; };
+struct Y3 { Y3()=delete; }; // expected-note {{partial 
specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}}
 template class U, typename... Z>
-struct Y3 {};
+struct Y3 {}; // expected-note {{partial specialization 
matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}}
 
 void f() {
   Y1 a;
   Y2 b; // expected-error {{ambiguous partial specializations}}
-  Y3 c;
+  Y3 c; // expected-error {{ambiguous partial 
specializations of 'Y3'}}

jcsxky wrote:

When instantiation, we are checking which one of the two partial specialization 
is more specialized. Obviously, the first one(`auto D`) is not more specialized 
than the second(`auto E`). When applied this patch, the second one is not more 
specialized than the first as well. This is because `isSameTemplateArg` return 
`false` and the result is not `TemplateDeductionResult::Success`.
Although we get correct result, it is not because of ignoring the 
type-constraint. Back to the quote, if we ignore the use of type-constraints 
for placeholder types, is the following example ill-formed due to their 
equivalent template arguments?
```cpp
template  constexpr bool True = true;
template  concept C = True;
template  concept D = C && sizeof(T) > 2;
template  concept E = D && alignof(T) > 1;

template
struct Y3 { Y3()=delete; };

template
struct Y3 { Y3()=delete; }; 

template
struct Y3 {};
```
But EDG, gcc and MSVC all accept this code. So I think the existing test is 
rejected may not be related to the quote. WDYT? @cor3ntin @zyn0217 @erichkeane 

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


[clang] [clang] visit constraint of NTTP (PR #91842)

2024-05-11 Thread Qizhi Hu via cfe-commits

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


[clang] [clang] visit constraint of NTTP (PR #91842)

2024-05-11 Thread Qizhi Hu via cfe-commits


@@ -79,14 +79,14 @@ template struct Y2 {}; // 
expected-note {{partial
 template class U, typename... Z>
 struct Y3 { Y3()=delete; };
 template class U, typename... Z>
-struct Y3 { Y3()=delete; };
+struct Y3 { Y3()=delete; }; // expected-note {{partial 
specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}}
 template class U, typename... Z>
-struct Y3 {};
+struct Y3 {}; // expected-note {{partial specialization 
matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}}
 
 void f() {
   Y1 a;
   Y2 b; // expected-error {{ambiguous partial specializations}}
-  Y3 c;
+  Y3 c; // expected-error {{ambiguous partial 
specializations of 'Y3'}}

jcsxky wrote:

I think the quote can explain why we should report error here. Maybe more work 
are required to find out where we do the ignore and how this patch impacts this 
case.

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


[clang] [clang] visit constraint of NTTP (PR #91842)

2024-05-11 Thread Qizhi Hu via cfe-commits

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


[clang] [clang] visit constraint of NTTP (PR #91842)

2024-05-11 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky created 
https://github.com/llvm/llvm-project/pull/91842

attempt to fix 
`isSameTemplateArg` returns incorrect result since clang didn't visit 
constraint of NTTP. Furthermore,  It makes class template partial 
specialization not more specialized than the class template itself.

>From ddc0fbb7a249fbc6f2d2795fda262b2e7ca0a4e9 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sat, 11 May 2024 14:04:23 +0800
Subject: [PATCH] [clang] visit constraint of NTTP

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/AST/StmtProfile.cpp |  5 +
 .../temp.fct/temp.func.order/p6.cpp   |  6 +++---
 clang/test/SemaCXX/PR77377.cpp| 19 +++
 4 files changed, 28 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR77377.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7c5dcc59c7016..30d359c582d3f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -707,6 +707,7 @@ Bug Fixes to C++ Support
   initialized, rather than evaluating them as a part of the larger manifestly 
constant evaluated
   expression.
 - Fix a bug in access control checking due to dealyed checking of friend 
declaration. Fixes (#GH12361).
+- Fix a bug on template class partial specialization due to traverse of 
constraint of NTTP. Fixes (#GH77377).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 8fb8940142eb0..0bb5a40d7350e 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2257,6 +2257,11 @@ void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
 const SubstNonTypeTemplateParmExpr *E) {
   // Profile exactly as the replacement expression.
   Visit(E->getReplacement());
+  if (auto *NTTP =
+  dyn_cast_if_present(E->getParameter());
+  NTTP && NTTP->getPlaceholderTypeConstraint()) {
+Visit(NTTP->getPlaceholderTypeConstraint());
+  }
 }
 
 void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp 
b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
index 9f44878da6254..5f9719a2dc561 100644
--- a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -79,14 +79,14 @@ template struct Y2 {}; // 
expected-note {{partial
 template class U, typename... Z>
 struct Y3 { Y3()=delete; };
 template class U, typename... Z>
-struct Y3 { Y3()=delete; };
+struct Y3 { Y3()=delete; }; // expected-note {{partial 
specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}}
 template class U, typename... Z>
-struct Y3 {};
+struct Y3 {}; // expected-note {{partial specialization 
matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}}
 
 void f() {
   Y1 a;
   Y2 b; // expected-error {{ambiguous partial specializations}}
-  Y3 c;
+  Y3 c; // expected-error {{ambiguous partial 
specializations of 'Y3'}}
 }
 
 // Per [temp.func.order]p6.2.2, specifically "if the function parameters that
diff --git a/clang/test/SemaCXX/PR77377.cpp b/clang/test/SemaCXX/PR77377.cpp
new file mode 100644
index 0..ae34809c3903d
--- /dev/null
+++ b/clang/test/SemaCXX/PR77377.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+// expected-no-diagnostics
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept same_as = is_same_v;
+
+template 
+struct A {};
+
+template  auto p>
+struct A {};
+
+A<0> a;

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


[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-10 Thread Qizhi Hu via cfe-commits

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


[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-09 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/91430

>From 002751420c7f71fa9903d94e135565793bd8c6f8 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Tue, 7 May 2024 22:32:39 +0800
Subject: [PATCH 1/2] [Clang][Sema] access checking of friend declaration
 should not be delayed

---
 clang/include/clang/Sema/Scope.h |  6 ++
 clang/lib/Parse/ParseDecl.cpp|  7 +--
 clang/lib/Sema/Scope.cpp |  2 ++
 clang/lib/Sema/SemaAccess.cpp| 12 ++--
 clang/test/SemaCXX/PR12361.cpp   | 30 ++
 5 files changed, 53 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR12361.cpp

diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 1752a25111a77..084db73034219 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -159,6 +159,9 @@ class Scope {
 
 /// This is a scope of type alias declaration.
 TypeAliasScope = 0x2000,
+
+/// This is a scope of friend declaration.
+FriendScope = 0x4000,
   };
 
 private:
@@ -586,6 +589,9 @@ class Scope {
   /// Determine whether this scope is a type alias scope.
   bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; }
 
+  /// Determine whether this scope is a friend scope.
+  bool isFriendScope() const { return getFlags() & Scope::FriendScope; }
+
   /// Returns if rhs has a higher scope depth than this.
   ///
   /// The caller is responsible for calling this only if one of the two scopes
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 2c11ae693c354..5b5fc02ad4023 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4331,9 +4331,12 @@ void Parser::ParseDeclarationSpecifiers(
 
 // friend
 case tok::kw_friend:
-  if (DSContext == DeclSpecContext::DSC_class)
+  if (DSContext == DeclSpecContext::DSC_class) {
 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
-  else {
+Scope *CurS = getCurScope();
+if (!isInvalid && CurS)
+  CurS->setFlags(CurS->getFlags() | Scope::FriendScope);
+  } else {
 PrevSpec = ""; // not actually used by the diagnostic
 DiagID = diag::err_friend_invalid_in_context;
 isInvalid = true;
diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp
index 11a41753a1bda..780aa898b1085 100644
--- a/clang/lib/Sema/Scope.cpp
+++ b/clang/lib/Sema/Scope.cpp
@@ -229,6 +229,8 @@ void Scope::dumpImpl(raw_ostream ) const {
   {ClassInheritanceScope, "ClassInheritanceScope"},
   {CatchScope, "CatchScope"},
   {OpenACCComputeConstructScope, "OpenACCComputeConstructScope"},
+  {TypeAliasScope, "TypeAliasScope"},
+  {FriendScope, "FriendScope"},
   };
 
   for (auto Info : FlagInfo) {
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 6a707eeb66d01..72c6736bb6648 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -1477,8 +1477,16 @@ static Sema::AccessResult CheckAccess(Sema , 
SourceLocation Loc,
   //   void foo(A::private_type);
   //   void B::foo(A::private_type);
   if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
-S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
-return Sema::AR_delayed;
+Scope *TS = S.getCurScope();
+bool IsFriendDeclaration = false;
+while (TS && !IsFriendDeclaration) {
+  IsFriendDeclaration = TS->isFriendScope();
+  TS = TS->getParent();
+}
+if (!IsFriendDeclaration) {
+  S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
+  return Sema::AR_delayed;
+}
   }
 
   EffectiveContext EC(S.CurContext);
diff --git a/clang/test/SemaCXX/PR12361.cpp b/clang/test/SemaCXX/PR12361.cpp
new file mode 100644
index 0..95ceb45b7ba04
--- /dev/null
+++ b/clang/test/SemaCXX/PR12361.cpp
@@ -0,0 +1,30 @@
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+ 
+class D {
+class E{
+class F{}; // expected-note{{implicitly declared private here}}
+friend  void foo(D::E::F& q);
+};
+friend  void foo(D::E::F& q); // expected-error{{'F' is a private member 
of 'D::E'}}
+};
+
+void foo(D::E::F& q) {}
+
+class D1 {
+class E1{
+class F1{}; // expected-note{{implicitly declared private here}}
+friend  D1::E1::F1 foo1();
+};
+friend  D1::E1::F1 foo1(); // expected-error{{'F1' is a private member of 
'D1::E1'}}
+};
+
+D1::E1::F1 foo1() { return D1::E1::F1(); }
+
+class D2 {
+class E2{
+class F2{};
+friend  void foo2();
+};
+friend  void foo2(){ D2::E2::F2 c;}
+};

>From 113c8508881babe25ab9d1daa9ab9a72018da124 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Wed, 8 May 2024 21:22:01 +0800
Subject: [PATCH 2/2] apply reviews

---
 

[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-08 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/91430

>From 324e4361b4cb1b17065b4dc7d4bdfa41fe781e7d Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Tue, 7 May 2024 22:32:39 +0800
Subject: [PATCH 1/2] [Clang][Sema] access checking of friend declaration
 should not be delayed

---
 clang/include/clang/Sema/Scope.h |  6 ++
 clang/lib/Parse/ParseDecl.cpp|  7 +--
 clang/lib/Sema/Scope.cpp |  2 ++
 clang/lib/Sema/SemaAccess.cpp| 12 ++--
 clang/test/SemaCXX/PR12361.cpp   | 30 ++
 5 files changed, 53 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR12361.cpp

diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 1752a25111a77..084db73034219 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -159,6 +159,9 @@ class Scope {
 
 /// This is a scope of type alias declaration.
 TypeAliasScope = 0x2000,
+
+/// This is a scope of friend declaration.
+FriendScope = 0x4000,
   };
 
 private:
@@ -586,6 +589,9 @@ class Scope {
   /// Determine whether this scope is a type alias scope.
   bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; }
 
+  /// Determine whether this scope is a friend scope.
+  bool isFriendScope() const { return getFlags() & Scope::FriendScope; }
+
   /// Returns if rhs has a higher scope depth than this.
   ///
   /// The caller is responsible for calling this only if one of the two scopes
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4e4b05b21383e..78a81c77f48c6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4332,9 +4332,12 @@ void Parser::ParseDeclarationSpecifiers(
 
 // friend
 case tok::kw_friend:
-  if (DSContext == DeclSpecContext::DSC_class)
+  if (DSContext == DeclSpecContext::DSC_class) {
 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
-  else {
+Scope *CurS = getCurScope();
+if (!isInvalid && CurS)
+  CurS->setFlags(CurS->getFlags() | Scope::FriendScope);
+  } else {
 PrevSpec = ""; // not actually used by the diagnostic
 DiagID = diag::err_friend_invalid_in_context;
 isInvalid = true;
diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp
index 11a41753a1bda..780aa898b1085 100644
--- a/clang/lib/Sema/Scope.cpp
+++ b/clang/lib/Sema/Scope.cpp
@@ -229,6 +229,8 @@ void Scope::dumpImpl(raw_ostream ) const {
   {ClassInheritanceScope, "ClassInheritanceScope"},
   {CatchScope, "CatchScope"},
   {OpenACCComputeConstructScope, "OpenACCComputeConstructScope"},
+  {TypeAliasScope, "TypeAliasScope"},
+  {FriendScope, "FriendScope"},
   };
 
   for (auto Info : FlagInfo) {
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 6a707eeb66d01..72c6736bb6648 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -1477,8 +1477,16 @@ static Sema::AccessResult CheckAccess(Sema , 
SourceLocation Loc,
   //   void foo(A::private_type);
   //   void B::foo(A::private_type);
   if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
-S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
-return Sema::AR_delayed;
+Scope *TS = S.getCurScope();
+bool IsFriendDeclaration = false;
+while (TS && !IsFriendDeclaration) {
+  IsFriendDeclaration = TS->isFriendScope();
+  TS = TS->getParent();
+}
+if (!IsFriendDeclaration) {
+  S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
+  return Sema::AR_delayed;
+}
   }
 
   EffectiveContext EC(S.CurContext);
diff --git a/clang/test/SemaCXX/PR12361.cpp b/clang/test/SemaCXX/PR12361.cpp
new file mode 100644
index 0..95ceb45b7ba04
--- /dev/null
+++ b/clang/test/SemaCXX/PR12361.cpp
@@ -0,0 +1,30 @@
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+ 
+class D {
+class E{
+class F{}; // expected-note{{implicitly declared private here}}
+friend  void foo(D::E::F& q);
+};
+friend  void foo(D::E::F& q); // expected-error{{'F' is a private member 
of 'D::E'}}
+};
+
+void foo(D::E::F& q) {}
+
+class D1 {
+class E1{
+class F1{}; // expected-note{{implicitly declared private here}}
+friend  D1::E1::F1 foo1();
+};
+friend  D1::E1::F1 foo1(); // expected-error{{'F1' is a private member of 
'D1::E1'}}
+};
+
+D1::E1::F1 foo1() { return D1::E1::F1(); }
+
+class D2 {
+class E2{
+class F2{};
+friend  void foo2();
+};
+friend  void foo2(){ D2::E2::F2 c;}
+};

>From 97723ff0ec73ac107bc74f222852e4c12b727eb0 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Wed, 8 May 2024 21:22:01 +0800
Subject: [PATCH 2/2] apply reviews

---
 

[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-08 Thread Qizhi Hu via cfe-commits


@@ -1477,8 +1477,16 @@ static Sema::AccessResult CheckAccess(Sema , 
SourceLocation Loc,
   //   void foo(A::private_type);
   //   void B::foo(A::private_type);
   if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
-S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
-return Sema::AR_delayed;
+Scope *TS = S.getCurScope();
+bool IsFriendDeclaration = false;
+while (TS && !IsFriendDeclaration) {
+  IsFriendDeclaration = TS->isFriendScope();
+  TS = TS->getParent();
+}
+if (!IsFriendDeclaration) {
+  S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
+  return Sema::AR_delayed;
+}

jcsxky wrote:

Added.

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


[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-08 Thread Qizhi Hu via cfe-commits


@@ -229,6 +229,8 @@ void Scope::dumpImpl(raw_ostream ) const {
   {ClassInheritanceScope, "ClassInheritanceScope"},
   {CatchScope, "CatchScope"},
   {OpenACCComputeConstructScope, "OpenACCComputeConstructScope"},
+  {TypeAliasScope, "TypeAliasScope"},

jcsxky wrote:

Removed. This will be done in a follow-up.

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


[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-08 Thread Qizhi Hu via cfe-commits


@@ -1477,8 +1477,16 @@ static Sema::AccessResult CheckAccess(Sema , 
SourceLocation Loc,
   //   void foo(A::private_type);

jcsxky wrote:

Done.

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


[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-08 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/91430

>From ec4f21b7823a89a793b0799b22c6bbdb0bfb4c52 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Tue, 7 May 2024 22:32:39 +0800
Subject: [PATCH 1/2] [Clang][Sema] access checking of friend declaration
 should not be delayed

---
 clang/include/clang/Sema/Scope.h |  6 ++
 clang/lib/Parse/ParseDecl.cpp|  7 +--
 clang/lib/Sema/Scope.cpp |  2 ++
 clang/lib/Sema/SemaAccess.cpp| 12 ++--
 clang/test/SemaCXX/PR12361.cpp   | 30 ++
 5 files changed, 53 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR12361.cpp

diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 1752a25111a77..084db73034219 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -159,6 +159,9 @@ class Scope {
 
 /// This is a scope of type alias declaration.
 TypeAliasScope = 0x2000,
+
+/// This is a scope of friend declaration.
+FriendScope = 0x4000,
   };
 
 private:
@@ -586,6 +589,9 @@ class Scope {
   /// Determine whether this scope is a type alias scope.
   bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; }
 
+  /// Determine whether this scope is a friend scope.
+  bool isFriendScope() const { return getFlags() & Scope::FriendScope; }
+
   /// Returns if rhs has a higher scope depth than this.
   ///
   /// The caller is responsible for calling this only if one of the two scopes
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4e4b05b21383e..78a81c77f48c6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4332,9 +4332,12 @@ void Parser::ParseDeclarationSpecifiers(
 
 // friend
 case tok::kw_friend:
-  if (DSContext == DeclSpecContext::DSC_class)
+  if (DSContext == DeclSpecContext::DSC_class) {
 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
-  else {
+Scope *CurS = getCurScope();
+if (!isInvalid && CurS)
+  CurS->setFlags(CurS->getFlags() | Scope::FriendScope);
+  } else {
 PrevSpec = ""; // not actually used by the diagnostic
 DiagID = diag::err_friend_invalid_in_context;
 isInvalid = true;
diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp
index 11a41753a1bda..780aa898b1085 100644
--- a/clang/lib/Sema/Scope.cpp
+++ b/clang/lib/Sema/Scope.cpp
@@ -229,6 +229,8 @@ void Scope::dumpImpl(raw_ostream ) const {
   {ClassInheritanceScope, "ClassInheritanceScope"},
   {CatchScope, "CatchScope"},
   {OpenACCComputeConstructScope, "OpenACCComputeConstructScope"},
+  {TypeAliasScope, "TypeAliasScope"},
+  {FriendScope, "FriendScope"},
   };
 
   for (auto Info : FlagInfo) {
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 6a707eeb66d01..72c6736bb6648 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -1477,8 +1477,16 @@ static Sema::AccessResult CheckAccess(Sema , 
SourceLocation Loc,
   //   void foo(A::private_type);
   //   void B::foo(A::private_type);
   if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
-S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
-return Sema::AR_delayed;
+Scope *TS = S.getCurScope();
+bool IsFriendDeclaration = false;
+while (TS && !IsFriendDeclaration) {
+  IsFriendDeclaration = TS->isFriendScope();
+  TS = TS->getParent();
+}
+if (!IsFriendDeclaration) {
+  S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
+  return Sema::AR_delayed;
+}
   }
 
   EffectiveContext EC(S.CurContext);
diff --git a/clang/test/SemaCXX/PR12361.cpp b/clang/test/SemaCXX/PR12361.cpp
new file mode 100644
index 0..95ceb45b7ba04
--- /dev/null
+++ b/clang/test/SemaCXX/PR12361.cpp
@@ -0,0 +1,30 @@
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+ 
+class D {
+class E{
+class F{}; // expected-note{{implicitly declared private here}}
+friend  void foo(D::E::F& q);
+};
+friend  void foo(D::E::F& q); // expected-error{{'F' is a private member 
of 'D::E'}}
+};
+
+void foo(D::E::F& q) {}
+
+class D1 {
+class E1{
+class F1{}; // expected-note{{implicitly declared private here}}
+friend  D1::E1::F1 foo1();
+};
+friend  D1::E1::F1 foo1(); // expected-error{{'F1' is a private member of 
'D1::E1'}}
+};
+
+D1::E1::F1 foo1() { return D1::E1::F1(); }
+
+class D2 {
+class E2{
+class F2{};
+friend  void foo2();
+};
+friend  void foo2(){ D2::E2::F2 c;}
+};

>From 77cfb6f93c8c91cfbe5d3d1ed4e90450afa026fa Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Wed, 8 May 2024 21:22:01 +0800
Subject: [PATCH 2/2] apply reviews

---
 

[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-08 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/91430

>From a4eee6db746e8de0743369f701d1b6a3fcc84754 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Tue, 7 May 2024 22:32:39 +0800
Subject: [PATCH 1/2] [Clang][Sema] access checking of friend declaration
 should not be delayed

---
 clang/include/clang/Sema/Scope.h |  6 ++
 clang/lib/Parse/ParseDecl.cpp|  7 +--
 clang/lib/Sema/Scope.cpp |  2 ++
 clang/lib/Sema/SemaAccess.cpp| 12 ++--
 clang/test/SemaCXX/PR12361.cpp   | 30 ++
 5 files changed, 53 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR12361.cpp

diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 1752a25111a77..084db73034219 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -159,6 +159,9 @@ class Scope {
 
 /// This is a scope of type alias declaration.
 TypeAliasScope = 0x2000,
+
+/// This is a scope of friend declaration.
+FriendScope = 0x4000,
   };
 
 private:
@@ -586,6 +589,9 @@ class Scope {
   /// Determine whether this scope is a type alias scope.
   bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; }
 
+  /// Determine whether this scope is a friend scope.
+  bool isFriendScope() const { return getFlags() & Scope::FriendScope; }
+
   /// Returns if rhs has a higher scope depth than this.
   ///
   /// The caller is responsible for calling this only if one of the two scopes
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4e4b05b21383e..78a81c77f48c6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4332,9 +4332,12 @@ void Parser::ParseDeclarationSpecifiers(
 
 // friend
 case tok::kw_friend:
-  if (DSContext == DeclSpecContext::DSC_class)
+  if (DSContext == DeclSpecContext::DSC_class) {
 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
-  else {
+Scope *CurS = getCurScope();
+if (!isInvalid && CurS)
+  CurS->setFlags(CurS->getFlags() | Scope::FriendScope);
+  } else {
 PrevSpec = ""; // not actually used by the diagnostic
 DiagID = diag::err_friend_invalid_in_context;
 isInvalid = true;
diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp
index 11a41753a1bda..780aa898b1085 100644
--- a/clang/lib/Sema/Scope.cpp
+++ b/clang/lib/Sema/Scope.cpp
@@ -229,6 +229,8 @@ void Scope::dumpImpl(raw_ostream ) const {
   {ClassInheritanceScope, "ClassInheritanceScope"},
   {CatchScope, "CatchScope"},
   {OpenACCComputeConstructScope, "OpenACCComputeConstructScope"},
+  {TypeAliasScope, "TypeAliasScope"},
+  {FriendScope, "FriendScope"},
   };
 
   for (auto Info : FlagInfo) {
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 6a707eeb66d01..72c6736bb6648 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -1477,8 +1477,16 @@ static Sema::AccessResult CheckAccess(Sema , 
SourceLocation Loc,
   //   void foo(A::private_type);
   //   void B::foo(A::private_type);
   if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
-S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
-return Sema::AR_delayed;
+Scope *TS = S.getCurScope();
+bool IsFriendDeclaration = false;
+while (TS && !IsFriendDeclaration) {
+  IsFriendDeclaration = TS->isFriendScope();
+  TS = TS->getParent();
+}
+if (!IsFriendDeclaration) {
+  S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
+  return Sema::AR_delayed;
+}
   }
 
   EffectiveContext EC(S.CurContext);
diff --git a/clang/test/SemaCXX/PR12361.cpp b/clang/test/SemaCXX/PR12361.cpp
new file mode 100644
index 0..95ceb45b7ba04
--- /dev/null
+++ b/clang/test/SemaCXX/PR12361.cpp
@@ -0,0 +1,30 @@
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+ 
+class D {
+class E{
+class F{}; // expected-note{{implicitly declared private here}}
+friend  void foo(D::E::F& q);
+};
+friend  void foo(D::E::F& q); // expected-error{{'F' is a private member 
of 'D::E'}}
+};
+
+void foo(D::E::F& q) {}
+
+class D1 {
+class E1{
+class F1{}; // expected-note{{implicitly declared private here}}
+friend  D1::E1::F1 foo1();
+};
+friend  D1::E1::F1 foo1(); // expected-error{{'F1' is a private member of 
'D1::E1'}}
+};
+
+D1::E1::F1 foo1() { return D1::E1::F1(); }
+
+class D2 {
+class E2{
+class F2{};
+friend  void foo2();
+};
+friend  void foo2(){ D2::E2::F2 c;}
+};

>From bce02c31f4b6601e7d031f74fa7e46d868a7d423 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Wed, 8 May 2024 21:22:01 +0800
Subject: [PATCH 2/2] apply reviews

---
 

[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-08 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> Can you add a changelog entry?

Ah, I forgot that! will be added when applying other reviews.

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


[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-07 Thread Qizhi Hu via cfe-commits

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


[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-07 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/91430

>From a4eee6db746e8de0743369f701d1b6a3fcc84754 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Tue, 7 May 2024 22:32:39 +0800
Subject: [PATCH] [Clang][Sema] access checking of friend declaration should
 not be delayed

---
 clang/include/clang/Sema/Scope.h |  6 ++
 clang/lib/Parse/ParseDecl.cpp|  7 +--
 clang/lib/Sema/Scope.cpp |  2 ++
 clang/lib/Sema/SemaAccess.cpp| 12 ++--
 clang/test/SemaCXX/PR12361.cpp   | 30 ++
 5 files changed, 53 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR12361.cpp

diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 1752a25111a77..084db73034219 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -159,6 +159,9 @@ class Scope {
 
 /// This is a scope of type alias declaration.
 TypeAliasScope = 0x2000,
+
+/// This is a scope of friend declaration.
+FriendScope = 0x4000,
   };
 
 private:
@@ -586,6 +589,9 @@ class Scope {
   /// Determine whether this scope is a type alias scope.
   bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; }
 
+  /// Determine whether this scope is a friend scope.
+  bool isFriendScope() const { return getFlags() & Scope::FriendScope; }
+
   /// Returns if rhs has a higher scope depth than this.
   ///
   /// The caller is responsible for calling this only if one of the two scopes
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4e4b05b21383e..78a81c77f48c6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4332,9 +4332,12 @@ void Parser::ParseDeclarationSpecifiers(
 
 // friend
 case tok::kw_friend:
-  if (DSContext == DeclSpecContext::DSC_class)
+  if (DSContext == DeclSpecContext::DSC_class) {
 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
-  else {
+Scope *CurS = getCurScope();
+if (!isInvalid && CurS)
+  CurS->setFlags(CurS->getFlags() | Scope::FriendScope);
+  } else {
 PrevSpec = ""; // not actually used by the diagnostic
 DiagID = diag::err_friend_invalid_in_context;
 isInvalid = true;
diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp
index 11a41753a1bda..780aa898b1085 100644
--- a/clang/lib/Sema/Scope.cpp
+++ b/clang/lib/Sema/Scope.cpp
@@ -229,6 +229,8 @@ void Scope::dumpImpl(raw_ostream ) const {
   {ClassInheritanceScope, "ClassInheritanceScope"},
   {CatchScope, "CatchScope"},
   {OpenACCComputeConstructScope, "OpenACCComputeConstructScope"},
+  {TypeAliasScope, "TypeAliasScope"},
+  {FriendScope, "FriendScope"},
   };
 
   for (auto Info : FlagInfo) {
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 6a707eeb66d01..72c6736bb6648 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -1477,8 +1477,16 @@ static Sema::AccessResult CheckAccess(Sema , 
SourceLocation Loc,
   //   void foo(A::private_type);
   //   void B::foo(A::private_type);
   if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
-S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
-return Sema::AR_delayed;
+Scope *TS = S.getCurScope();
+bool IsFriendDeclaration = false;
+while (TS && !IsFriendDeclaration) {
+  IsFriendDeclaration = TS->isFriendScope();
+  TS = TS->getParent();
+}
+if (!IsFriendDeclaration) {
+  S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
+  return Sema::AR_delayed;
+}
   }
 
   EffectiveContext EC(S.CurContext);
diff --git a/clang/test/SemaCXX/PR12361.cpp b/clang/test/SemaCXX/PR12361.cpp
new file mode 100644
index 0..95ceb45b7ba04
--- /dev/null
+++ b/clang/test/SemaCXX/PR12361.cpp
@@ -0,0 +1,30 @@
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+ 
+class D {
+class E{
+class F{}; // expected-note{{implicitly declared private here}}
+friend  void foo(D::E::F& q);
+};
+friend  void foo(D::E::F& q); // expected-error{{'F' is a private member 
of 'D::E'}}
+};
+
+void foo(D::E::F& q) {}
+
+class D1 {
+class E1{
+class F1{}; // expected-note{{implicitly declared private here}}
+friend  D1::E1::F1 foo1();
+};
+friend  D1::E1::F1 foo1(); // expected-error{{'F1' is a private member of 
'D1::E1'}}
+};
+
+D1::E1::F1 foo1() { return D1::E1::F1(); }
+
+class D2 {
+class E2{
+class F2{};
+friend  void foo2();
+};
+friend  void foo2(){ D2::E2::F2 c;}
+};

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


[clang] [Clang][Sema] access checking of friend declaration should not be delayed (PR #91430)

2024-05-07 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky created 
https://github.com/llvm/llvm-project/pull/91430

attempt to fix https://github.com/llvm/llvm-project/issues/12361
Consider this example:
```cpp
class D {
class E{
class F{}; // expected-note{{implicitly declared private here}}
friend  void foo(D::E::F& q);
};
friend  void foo(D::E::F& q);
};

void foo(D::E::F& q) {}
```
The first friend declaration of foo is correct. After that, the second  friend 
declaration delayed access checking and set its previous declaration to be the 
first one. When doing access checking of `F`(which is private filed of `E`), we 
put its canonical declaration(the first friend declaration) into 
`EffectiveContext.Functions`. Actually, we are still checking the first one. 
This is incorrect due to the delayed checking.
Creating a new scope to indicate we are parsing a friend declaration and doing 
access checking in time.

>From 836a66f221777e5c3bdd78087f82c2567854c10c Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Tue, 7 May 2024 22:32:39 +0800
Subject: [PATCH] [Clang][Sema] access checking of friend declaration should
 not be delayed

---
 clang/include/clang/Sema/Scope.h |  6 ++
 clang/lib/Parse/ParseDecl.cpp|  7 +--
 clang/lib/Sema/Scope.cpp |  2 ++
 clang/lib/Sema/SemaAccess.cpp|  8 +++-
 clang/test/SemaCXX/PR12361.cpp   | 30 ++
 5 files changed, 50 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR12361.cpp

diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 1752a25111a77..084db73034219 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -159,6 +159,9 @@ class Scope {
 
 /// This is a scope of type alias declaration.
 TypeAliasScope = 0x2000,
+
+/// This is a scope of friend declaration.
+FriendScope = 0x4000,
   };
 
 private:
@@ -586,6 +589,9 @@ class Scope {
   /// Determine whether this scope is a type alias scope.
   bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; }
 
+  /// Determine whether this scope is a friend scope.
+  bool isFriendScope() const { return getFlags() & Scope::FriendScope; }
+
   /// Returns if rhs has a higher scope depth than this.
   ///
   /// The caller is responsible for calling this only if one of the two scopes
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4e4b05b21383e..78a81c77f48c6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4332,9 +4332,12 @@ void Parser::ParseDeclarationSpecifiers(
 
 // friend
 case tok::kw_friend:
-  if (DSContext == DeclSpecContext::DSC_class)
+  if (DSContext == DeclSpecContext::DSC_class) {
 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
-  else {
+Scope *CurS = getCurScope();
+if (!isInvalid && CurS)
+  CurS->setFlags(CurS->getFlags() | Scope::FriendScope);
+  } else {
 PrevSpec = ""; // not actually used by the diagnostic
 DiagID = diag::err_friend_invalid_in_context;
 isInvalid = true;
diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp
index 11a41753a1bda..780aa898b1085 100644
--- a/clang/lib/Sema/Scope.cpp
+++ b/clang/lib/Sema/Scope.cpp
@@ -229,6 +229,8 @@ void Scope::dumpImpl(raw_ostream ) const {
   {ClassInheritanceScope, "ClassInheritanceScope"},
   {CatchScope, "CatchScope"},
   {OpenACCComputeConstructScope, "OpenACCComputeConstructScope"},
+  {TypeAliasScope, "TypeAliasScope"},
+  {FriendScope, "FriendScope"},
   };
 
   for (auto Info : FlagInfo) {
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 6a707eeb66d01..ded88da510525 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -1476,7 +1476,13 @@ static Sema::AccessResult CheckAccess(Sema , 
SourceLocation Loc,
   // Or we might be parsing something that will turn out to be a friend:
   //   void foo(A::private_type);
   //   void B::foo(A::private_type);
-  if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
+  Scope *TS = S.getCurScope();
+  bool IsFriendDeclaration = false;
+  while (TS && !IsFriendDeclaration) {
+IsFriendDeclaration = TS->isFriendScope();
+TS = TS->getParent();
+  }
+  if (S.DelayedDiagnostics.shouldDelayDiagnostics() && !IsFriendDeclaration) {
 S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
 return Sema::AR_delayed;
   }
diff --git a/clang/test/SemaCXX/PR12361.cpp b/clang/test/SemaCXX/PR12361.cpp
new file mode 100644
index 0..95ceb45b7ba04
--- /dev/null
+++ b/clang/test/SemaCXX/PR12361.cpp
@@ -0,0 +1,30 @@
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+ 
+class D {
+class E{
+class F{}; // expected-note{{implicitly declared private here}}
+friend  void 

[clang] [Clang][Sema] Improve support for explicit specializations of constrained member functions & member function templates (PR #88963)

2024-05-03 Thread Qizhi Hu via cfe-commits


@@ -275,6 +275,13 @@ Response HandleFunction(Sema , const FunctionDecl 
*Function,
  TemplateArgs->asArray(),
  /*Final=*/false);
 
+if (RelativeToPrimary &&
+(Function->getTemplateSpecializationKind() ==
+ TSK_ExplicitSpecialization ||

jcsxky wrote:

@sdkrystian but gcc fails on the testcase you provided.

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


[clang] [Clang][Sema] fix a bug on constraint check with template friend function (PR #90646)

2024-05-02 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> This still doesn't handle cases such as:
> 
> ```c++
> template
> concept E = sizeof(T) == sizeof(U) && sizeof(V) == sizeof(W);
> 
> template // T = char
> struct A
> {
> template // U = signed char
> struct B
> {
> template // V = int, W = int, X = 
> short
> requires E // incorrectly substitutes T = int, U = short, 
> V = int, V = int
> static void f();
> };
> };
> 
> 
> template // T = int, U = int
> struct C
> {
> template // V = short
> struct D
> {
> friend void A::B::f();
> };
> };
> 
> template struct C::D;
> 
> extern template void A::B::f();
> ```
> 
> (which is handled by 
> [be79079](https://github.com/llvm/llvm-project/commit/be79079507ffbd9b29683498f405dc2c32dd8ba7))

Thanks for your patience and testcases! They really make me understand these 
related issues more clearly.

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


[clang] [Clang][Sema] Improve support for explicit specializations of constrained member functions & member function templates (PR #88963)

2024-05-02 Thread Qizhi Hu via cfe-commits


@@ -275,6 +275,13 @@ Response HandleFunction(Sema , const FunctionDecl 
*Function,
  TemplateArgs->asArray(),
  /*Final=*/false);
 
+if (RelativeToPrimary &&
+(Function->getTemplateSpecializationKind() ==
+ TSK_ExplicitSpecialization ||

jcsxky wrote:

This testcase runs OK before 
[be79079](https://github.com/llvm/llvm-project/pull/88963/commits/be79079507ffbd9b29683498f405dc2c32dd8ba7)
 applied and it may not be related to the condition 
`Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization`.

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


[clang] [Clang][Sema] fix a bug on constraint check with template friend function (PR #90646)

2024-05-02 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> I agree with @sdkrystian, even though the test crashes for maybe yet another 
> reason, it demonstrates you can friend a function from a different template 
> context, so comparing the depths from different branches is not helpful.

@mizvekov I missed the case which friend function is declared in an inner 
class, and 
[3d27f11](https://github.com/llvm/llvm-project/pull/90646/commits/3d27f11d79b00608bf9135bcc4b4cb859027933a)
 demonstrates the comparison works fine.

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


[clang] [Clang][Sema] fix a bug on constraint check with template friend function (PR #90646)

2024-05-02 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/90646

>From 50aa5b64f6d2cf98706bfb4792f274bd071e3b9c Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Wed, 1 May 2024 02:25:04 +0800
Subject: [PATCH 1/2] [Clang][Sema] fix a bug on constraint check with template
 friend function

---
 clang/docs/ReleaseNotes.rst|  1 +
 clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 +++
 clang/test/SemaCXX/PR90349.cpp | 43 ++
 3 files changed, 58 insertions(+)
 create mode 100644 clang/test/SemaCXX/PR90349.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2c5308fbcb319a..ac90e3933798cb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -630,6 +630,7 @@ Bug Fixes to C++ Support
 - Fix a bug on template partial specialization with issue on deduction of 
nontype template parameter
   whose type is `decltype(auto)`. Fixes (#GH68885).
 - Clang now correctly treats the noexcept-specifier of a friend function to be 
a complete-class context.
+- Fix a bug on constraint check with template friend function. Fixes 
(#GH90349).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 3a9fd906b7af86..1805f8f6e5ad90 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -281,6 +281,20 @@ Response HandleFunction(Sema , const FunctionDecl 
*Function,
 if (Function->getPrimaryTemplate()->isMemberSpecialization())
   return Response::Done();
 
+if (Function->getFriendObjectKind())
+  if (const ClassTemplateSpecializationDecl *TD =
+  dyn_cast(
+  Function->getLexicalDeclContext())) {
+const CXXRecordDecl *TemplatePattern =
+TD->getTemplateInstantiationPattern();
+const FunctionDecl *FunctionPattern =
+Function->getTemplateInstantiationPattern();
+if (TemplatePattern && FunctionPattern &&
+TemplatePattern->getTemplateDepth() ==
+FunctionPattern->getTemplateDepth())
+  return Response::Done();
+  }
+
 // If this function is a generic lambda specialization, we are done.
 if (!ForConstraintInstantiation &&
 isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function)) {
diff --git a/clang/test/SemaCXX/PR90349.cpp b/clang/test/SemaCXX/PR90349.cpp
new file mode 100644
index 00..6a4b5c21e88f3b
--- /dev/null
+++ b/clang/test/SemaCXX/PR90349.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+// expected-no-diagnostics
+
+namespace std {
+template
+concept floating_point = __is_same(T,double) || __is_same(T,float);
+
+template
+concept integral = __is_same(T,int);
+
+}
+
+template
+class Blob;
+
+template
+Blob MakeBlob();
+
+template
+class Blob {
+private:
+Blob() {}
+
+friend Blob MakeBlob();
+};
+
+template
+Blob MakeBlob()
+{
+return Blob();
+}
+
+template
+Blob FindBlobs()
+{
+return MakeBlob();
+}
+
+int main(int argc, const char * argv[]) {
+FindBlobs();
+return 0;
+}

>From 3d27f11d79b00608bf9135bcc4b4cb859027933a Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Thu, 2 May 2024 20:05:10 +0800
Subject: [PATCH 2/2] continue to handle context instead of finish

---
 clang/lib/Sema/SemaTemplateInstantiate.cpp |  2 +-
 clang/test/SemaCXX/PR90349.cpp | 24 ++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 1805f8f6e5ad90..22789c72b2c90f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -292,7 +292,7 @@ Response HandleFunction(Sema , const FunctionDecl 
*Function,
 if (TemplatePattern && FunctionPattern &&
 TemplatePattern->getTemplateDepth() ==
 FunctionPattern->getTemplateDepth())
-  return Response::Done();
+  return Response::UseNextDecl(Function);
   }
 
 // If this function is a generic lambda specialization, we are done.
diff --git a/clang/test/SemaCXX/PR90349.cpp b/clang/test/SemaCXX/PR90349.cpp
index 6a4b5c21e88f3b..570a49fd2073bb 100644
--- a/clang/test/SemaCXX/PR90349.cpp
+++ b/clang/test/SemaCXX/PR90349.cpp
@@ -41,3 +41,27 @@ int main(int argc, const char * argv[]) {
 FindBlobs();
 return 0;
 }
+
+template
+concept D = sizeof(T) == sizeof(U);
+
+template
+struct A
+{
+template requires D
+static void f();
+};
+
+template
+struct B
+{
+template
+struct C
+{
+friend void A::f();
+};
+};
+
+template struct B::C;
+
+extern template void A::f(); // crash here

___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[clang] [Clang][Sema] Improve support for explicit specializations of constrained member functions & member function templates (PR #88963)

2024-05-02 Thread Qizhi Hu via cfe-commits


@@ -275,6 +275,13 @@ Response HandleFunction(Sema , const FunctionDecl 
*Function,
  TemplateArgs->asArray(),
  /*Final=*/false);
 
+if (RelativeToPrimary &&
+(Function->getTemplateSpecializationKind() ==
+ TSK_ExplicitSpecialization ||

jcsxky wrote:

Is this condition `Function->getTemplateSpecializationKind() == 
TSK_ExplicitSpecialization` necessary? I removed it and all testcases passed. 
Could you please add a testcase to cover it which would fail without this 
condition?

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


[clang] [Clang][Sema] fix a bug on constraint check with template friend function (PR #90646)

2024-05-01 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> ```c++
> template
> concept D = sizeof(T) == sizeof(U);
> 
> template
> struct A
> {
> template requires D
> static void f();
> };
> 
> template
> struct B
> {
> template
> struct C
> {
> friend void A::f();
> };
> };
> 
> template struct B::C;
> 
> extern template void A::f(); // crash here
> ```
> 
> @jcsxky causes crash with and without this patch applied.

Thanks for your feedback! This may be another issue. clang trunk crashes with 
this case. 

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


[clang] [Clang][Sema] fix a bug on constraint check with template friend function (PR #90646)

2024-05-01 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

Windows CI failed with some unrelated files.

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


[clang] [Clang][Sema] fix a bug on constraint check with template friend function (PR #90646)

2024-04-30 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> I'm actually working on constraint checking for function template 
> specializations in #88963. I don't think this patch is quite right... this 
> will cause a crash if the befriended function is a member of a class template 
> specialization. Relative to the changes in #88963, I believe the correct fix 
> would be to change line 278 to:
> 
> ```c++
> if (RelativeToPrimary &&
> (Function->getTemplateSpecializationKind() ==
>  TSK_ExplicitSpecialization ||
>  (Function->getFriendObjectKind() &&
>   !Function->getPrimaryTemplate()->getFriendObjectKind(
>   return Response::UseNextDecl(Function);
> ```
> 
> I added a commit to #88963 which makes this change 
> ([be79079](https://github.com/llvm/llvm-project/commit/be79079507ffbd9b29683498f405dc2c32dd8ba7))
> 
> cc @erichkeane

Only when the friend function doesn't use any other new template parameters, 
i.e. their depth is equal can we skip to add the outer arguments to `MTAL`.

> this will cause a crash if the befriended function is a member of a class 
> template specialization

Could you please provide a testcase?

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


[clang] [Clang][Sema] fix a bug on constraint check with template friend function (PR #90646)

2024-04-30 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky created 
https://github.com/llvm/llvm-project/pull/90646

attempt to fix https://github.com/llvm/llvm-project/issues/90349
Skip to add outer class template arguments to `MTAL` when the friend function 
has the same depth with its lexical context(`CXXRecordDecl`).

>From e2785999ed38cd3b0addcf28d9122ecf8100d908 Mon Sep 17 00:00:00 2001
From: Qizhi Hu <836744...@qq.com>
Date: Wed, 1 May 2024 02:25:04 +0800
Subject: [PATCH] [Clang][Sema] fix a bug on constraint check with template
 friend function

---
 clang/docs/ReleaseNotes.rst|  1 +
 clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 +++
 clang/test/SemaCXX/PR90349.cpp | 43 ++
 3 files changed, 58 insertions(+)
 create mode 100644 clang/test/SemaCXX/PR90349.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c11f117cd6e8b4..ec10c82a3a5403 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -627,6 +627,7 @@ Bug Fixes to C++ Support
 - Fix a bug on template partial specialization with issue on deduction of 
nontype template parameter
   whose type is `decltype(auto)`. Fixes (#GH68885).
 - Clang now correctly treats the noexcept-specifier of a friend function to be 
a complete-class context.
+- Fix a bug on constraint check with template friend function. Fixes 
(#GH90349).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 3a9fd906b7af86..1805f8f6e5ad90 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -281,6 +281,20 @@ Response HandleFunction(Sema , const FunctionDecl 
*Function,
 if (Function->getPrimaryTemplate()->isMemberSpecialization())
   return Response::Done();
 
+if (Function->getFriendObjectKind())
+  if (const ClassTemplateSpecializationDecl *TD =
+  dyn_cast(
+  Function->getLexicalDeclContext())) {
+const CXXRecordDecl *TemplatePattern =
+TD->getTemplateInstantiationPattern();
+const FunctionDecl *FunctionPattern =
+Function->getTemplateInstantiationPattern();
+if (TemplatePattern && FunctionPattern &&
+TemplatePattern->getTemplateDepth() ==
+FunctionPattern->getTemplateDepth())
+  return Response::Done();
+  }
+
 // If this function is a generic lambda specialization, we are done.
 if (!ForConstraintInstantiation &&
 isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function)) {
diff --git a/clang/test/SemaCXX/PR90349.cpp b/clang/test/SemaCXX/PR90349.cpp
new file mode 100644
index 00..6a4b5c21e88f3b
--- /dev/null
+++ b/clang/test/SemaCXX/PR90349.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+// expected-no-diagnostics
+
+namespace std {
+template
+concept floating_point = __is_same(T,double) || __is_same(T,float);
+
+template
+concept integral = __is_same(T,int);
+
+}
+
+template
+class Blob;
+
+template
+Blob MakeBlob();
+
+template
+class Blob {
+private:
+Blob() {}
+
+friend Blob MakeBlob();
+};
+
+template
+Blob MakeBlob()
+{
+return Blob();
+}
+
+template
+Blob FindBlobs()
+{
+return MakeBlob();
+}
+
+int main(int argc, const char * argv[]) {
+FindBlobs();
+return 0;
+}

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


[clang] [Clang][Sema] Fix a bug on template partial specialization with issue on deduction of nontype template parameter (PR #90376)

2024-04-30 Thread Qizhi Hu via cfe-commits

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


[clang] [Clang][Sema] Fix a bug on template partial specialization with issue on deduction of nontype template parameter (PR #90376)

2024-04-30 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/90376

>From c5c67ed879fc58e5371de6fc8296b7b6f653a072 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sun, 28 Apr 2024 14:24:30 +0800
Subject: [PATCH] [Clang][Sema] Fix a bug on template partial specialization
 with issue on deduction of nontype tempalte parameter

---
 clang/docs/ReleaseNotes.rst  |  2 ++
 clang/include/clang/Sema/Sema.h  | 10 ++
 clang/lib/Sema/SemaTemplate.cpp  | 19 +++
 clang/lib/Sema/SemaTemplateDeduction.cpp | 10 ++
 clang/test/SemaCXX/PR68885.cpp   | 21 +
 5 files changed, 50 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR68885.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 98c80b6017f604..1abc00a25f1f42 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -612,6 +612,8 @@ Bug Fixes to C++ Support
 - Fix CTAD for ``std::initializer_list``. This allows 
``std::initializer_list{1, 2, 3}`` to be deduced as
   ``std::initializer_list`` as intended.
 - Fix a bug on template partial specialization whose template parameter is 
`decltype(auto)`.
+- Fix a bug on template partial specialization with issue on deduction of 
nontype template parameter
+  whose type is `decltype(auto)`. Fixes (#GH68885).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1ca523ec88c2f9..809b9c4498f697 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9249,7 +9249,8 @@ class Sema final : public SemaBase {
   void NoteTemplateParameterLocation(const NamedDecl );
 
   ExprResult BuildExpressionFromDeclTemplateArgument(
-  const TemplateArgument , QualType ParamType, SourceLocation Loc);
+  const TemplateArgument , QualType ParamType, SourceLocation Loc,
+  NamedDecl *TemplateParam = nullptr);
   ExprResult
   BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument ,
  SourceLocation Loc);
@@ -9572,9 +9573,10 @@ class Sema final : public SemaBase {
 
   bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg);
 
-  TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument 
,
-QualType NTTPType,
-SourceLocation Loc);
+  TemplateArgumentLoc
+  getTrivialTemplateArgumentLoc(const TemplateArgument , QualType NTTPType,
+SourceLocation Loc,
+NamedDecl *TemplateParam = nullptr);
 
   /// Get a template argument mapping the given template parameter to itself,
   /// e.g. for X in \c template, this would return an expression 
template
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index ed5507c0ec0100..3c2a5a4ac47e69 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8438,10 +8438,9 @@ void Sema::NoteTemplateParameterLocation(const NamedDecl 
) {
 /// declaration and the type of its corresponding non-type template
 /// parameter, produce an expression that properly refers to that
 /// declaration.
-ExprResult
-Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument ,
-  QualType ParamType,
-  SourceLocation Loc) {
+ExprResult Sema::BuildExpressionFromDeclTemplateArgument(
+const TemplateArgument , QualType ParamType, SourceLocation Loc,
+NamedDecl *TemplateParam) {
   // C++ [temp.param]p8:
   //
   //   A non-type template-parameter of type "array of T" or
@@ -8508,6 +8507,18 @@ Sema::BuildExpressionFromDeclTemplateArgument(const 
TemplateArgument ,
   } else {
 assert(ParamType->isReferenceType() &&
"unexpected type for decl template argument");
+if (NonTypeTemplateParmDecl *NTTP =
+dyn_cast_if_present(TemplateParam)) {
+  QualType TemplateParamType = NTTP->getType();
+  const AutoType *AT = TemplateParamType->getAs();
+  if (AT && AT->isDecltypeAuto()) {
+RefExpr = new (getASTContext()) SubstNonTypeTemplateParmExpr(
+ParamType->getPointeeType(), RefExpr.get()->getValueKind(),
+RefExpr.get()->getExprLoc(), RefExpr.get(), VD, NTTP->getIndex(),
+/*PackIndex=*/std::nullopt,
+/*RefParam=*/true);
+  }
+}
   }
 
   // At this point we should have the right value category.
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index c3815bca038554..e93f7bd842e444 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2639,7 +2639,8 @@ static bool isSameTemplateArg(ASTContext ,
 /// argument.
 TemplateArgumentLoc
 

[clang] [Clang][Sema] fix a bug on template partial specialization (PR #89862)

2024-04-30 Thread Qizhi Hu via cfe-commits

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


[clang] [Clang][Sema] fix a bug on template partial specialization (PR #89862)

2024-04-30 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/89862

>From 242b88a37f08bb66bcdde5e5b30c43553107d29c Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Wed, 24 Apr 2024 09:37:53 +0800
Subject: [PATCH] [Clang][Sema] fix a bug on template partial specialization

---
 clang/docs/ReleaseNotes.rst |  1 +
 clang/lib/Sema/SemaTemplate.cpp |  2 +-
 ...dentical-type-primary-partial-specialization.cpp | 13 +
 3 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 
clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4c0fe5bcf6b122..98c80b6017f604 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -611,6 +611,7 @@ Bug Fixes to C++ Support
   immediate function context.
 - Fix CTAD for ``std::initializer_list``. This allows 
``std::initializer_list{1, 2, 3}`` to be deduced as
   ``std::initializer_list`` as intended.
+- Fix a bug on template partial specialization whose template parameter is 
`decltype(auto)`.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index bbcb7c33a98579..ed5507c0ec0100 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7706,7 +7706,7 @@ ExprResult 
Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
 // FIXME: The language rules don't say what happens in this case.
 // FIXME: We get an opaque dependent type out of decltype(auto) if the
 // expression is merely instantiation-dependent; is this enough?
-if (CTAK == CTAK_Deduced && Arg->isTypeDependent()) {
+if (Arg->isTypeDependent()) {
   auto *AT = dyn_cast(DeducedT);
   if (AT && AT->isDecltypeAuto()) {
 SugaredConverted = TemplateArgument(Arg);
diff --git 
a/clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp 
b/clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp
new file mode 100644
index 00..ad51ca8252ef50
--- /dev/null
+++ b/clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+template 
+struct S { // expected-note {{previous definition is here}}
+static constexpr int i = 42;
+};
+
+template 
+struct S { // expected-error {{class template partial specialization does 
not specialize any template argument; to define the primary template, remove 
the template argument list}} \
+  // expected-error {{redefinition of 'S'}}
+static constexpr int i = 0;
+};

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


[clang] [Clang][Sema] Fix a bug on template partial specialization with issue on deduction of nontype tempalte parameter (PR #90376)

2024-04-28 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/90376

>From 947096950049ac7047a26335a993e48c1fa5c16d Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sun, 28 Apr 2024 14:24:30 +0800
Subject: [PATCH] [Clang][Sema] Fix a bug on template partial specialization
 with issue on deduction of nontype tempalte parameter

---
 clang/docs/ReleaseNotes.rst  |  2 ++
 clang/include/clang/Sema/Sema.h  | 10 ++
 clang/lib/Sema/SemaTemplate.cpp  | 19 +++
 clang/lib/Sema/SemaTemplateDeduction.cpp | 10 ++
 clang/test/SemaCXX/PR68885.cpp   | 21 +
 5 files changed, 50 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR68885.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 64a523a6f25fc2..64533f94815eb3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -590,6 +590,8 @@ Bug Fixes to C++ Support
 - Fixed a use-after-free bug in parsing of type constraints with default 
arguments that involve lambdas. (#GH67235)
 - Fixed bug in which the body of a consteval lambda within a template was not 
parsed as within an
   immediate function context.
+- Fix a bug on template partial specialization with issue on deduction of 
nontype tempalte parameter
+  whose type is `decltype(auto)`. Fixes (#GH68885).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1ca523ec88c2f9..809b9c4498f697 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9249,7 +9249,8 @@ class Sema final : public SemaBase {
   void NoteTemplateParameterLocation(const NamedDecl );
 
   ExprResult BuildExpressionFromDeclTemplateArgument(
-  const TemplateArgument , QualType ParamType, SourceLocation Loc);
+  const TemplateArgument , QualType ParamType, SourceLocation Loc,
+  NamedDecl *TemplateParam = nullptr);
   ExprResult
   BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument ,
  SourceLocation Loc);
@@ -9572,9 +9573,10 @@ class Sema final : public SemaBase {
 
   bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg);
 
-  TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument 
,
-QualType NTTPType,
-SourceLocation Loc);
+  TemplateArgumentLoc
+  getTrivialTemplateArgumentLoc(const TemplateArgument , QualType NTTPType,
+SourceLocation Loc,
+NamedDecl *TemplateParam = nullptr);
 
   /// Get a template argument mapping the given template parameter to itself,
   /// e.g. for X in \c template, this would return an expression 
template
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index bbcb7c33a98579..04f87fff550370 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8438,10 +8438,9 @@ void Sema::NoteTemplateParameterLocation(const NamedDecl 
) {
 /// declaration and the type of its corresponding non-type template
 /// parameter, produce an expression that properly refers to that
 /// declaration.
-ExprResult
-Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument ,
-  QualType ParamType,
-  SourceLocation Loc) {
+ExprResult Sema::BuildExpressionFromDeclTemplateArgument(
+const TemplateArgument , QualType ParamType, SourceLocation Loc,
+NamedDecl *TemplateParam) {
   // C++ [temp.param]p8:
   //
   //   A non-type template-parameter of type "array of T" or
@@ -8508,6 +8507,18 @@ Sema::BuildExpressionFromDeclTemplateArgument(const 
TemplateArgument ,
   } else {
 assert(ParamType->isReferenceType() &&
"unexpected type for decl template argument");
+if (NonTypeTemplateParmDecl *NTTP =
+dyn_cast_if_present(TemplateParam)) {
+  QualType TemplateParamType = NTTP->getType();
+  const AutoType *AT = TemplateParamType->getAs();
+  if (AT && AT->isDecltypeAuto()) {
+RefExpr = new (getASTContext()) SubstNonTypeTemplateParmExpr(
+ParamType->getPointeeType(), RefExpr.get()->getValueKind(),
+RefExpr.get()->getExprLoc(), RefExpr.get(), VD, NTTP->getIndex(),
+/*PackIndex=*/std::nullopt,
+/*RefParam=*/true);
+  }
+}
   }
 
   // At this point we should have the right value category.
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index c3815bca038554..e93f7bd842e444 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2639,7 +2639,8 @@ static bool isSameTemplateArg(ASTContext ,
 /// argument.
 TemplateArgumentLoc
 

[clang] [Clang][Sema] Fix a bug on template partial specialization with issue on deduction of nontype tempalte parameter (PR #90376)

2024-04-28 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/90376

>From cb7acd79aea4af3e92b5317e55fb43cabc7ebb40 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sun, 28 Apr 2024 14:24:30 +0800
Subject: [PATCH] [Clang][Sema] Fix a bug on template partial specialization
 with issue on deduction of nontype tempalte parameter

---
 clang/docs/ReleaseNotes.rst  |  2 ++
 clang/include/clang/Sema/Sema.h  | 10 ++
 clang/lib/Sema/SemaTemplate.cpp  | 19 +++
 clang/lib/Sema/SemaTemplateDeduction.cpp | 10 ++
 clang/test/SemaCXX/PR68885.cpp   | 21 +
 5 files changed, 50 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR68885.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 64a523a6f25fc2..64533f94815eb3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -590,6 +590,8 @@ Bug Fixes to C++ Support
 - Fixed a use-after-free bug in parsing of type constraints with default 
arguments that involve lambdas. (#GH67235)
 - Fixed bug in which the body of a consteval lambda within a template was not 
parsed as within an
   immediate function context.
+- Fix a bug on template partial specialization with issue on deduction of 
nontype tempalte parameter
+  whose type is `decltype(auto)`. Fixes (#GH68885).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1ca523ec88c2f9..809b9c4498f697 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9249,7 +9249,8 @@ class Sema final : public SemaBase {
   void NoteTemplateParameterLocation(const NamedDecl );
 
   ExprResult BuildExpressionFromDeclTemplateArgument(
-  const TemplateArgument , QualType ParamType, SourceLocation Loc);
+  const TemplateArgument , QualType ParamType, SourceLocation Loc,
+  NamedDecl *TemplateParam = nullptr);
   ExprResult
   BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument ,
  SourceLocation Loc);
@@ -9572,9 +9573,10 @@ class Sema final : public SemaBase {
 
   bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg);
 
-  TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument 
,
-QualType NTTPType,
-SourceLocation Loc);
+  TemplateArgumentLoc
+  getTrivialTemplateArgumentLoc(const TemplateArgument , QualType NTTPType,
+SourceLocation Loc,
+NamedDecl *TemplateParam = nullptr);
 
   /// Get a template argument mapping the given template parameter to itself,
   /// e.g. for X in \c template, this would return an expression 
template
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index bbcb7c33a98579..c91002592781c8 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8438,10 +8438,9 @@ void Sema::NoteTemplateParameterLocation(const NamedDecl 
) {
 /// declaration and the type of its corresponding non-type template
 /// parameter, produce an expression that properly refers to that
 /// declaration.
-ExprResult
-Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument ,
-  QualType ParamType,
-  SourceLocation Loc) {
+ExprResult Sema::BuildExpressionFromDeclTemplateArgument(
+const TemplateArgument , QualType ParamType, SourceLocation Loc,
+NamedDecl *TemplateParam) {
   // C++ [temp.param]p8:
   //
   //   A non-type template-parameter of type "array of T" or
@@ -8508,6 +8507,18 @@ Sema::BuildExpressionFromDeclTemplateArgument(const 
TemplateArgument ,
   } else {
 assert(ParamType->isReferenceType() &&
"unexpected type for decl template argument");
+if (NonTypeTemplateParmDecl *NTTP =
+dyn_cast_if_present(TemplateParam)) {
+  QualType TemplateParamType = NTTP->getType();
+  const AutoType *AT = TemplateParamType->getAs();
+  if (AT && AT->isDecltypeAuto()) {
+RefExpr = new (getASTContext()) SubstNonTypeTemplateParmExpr(
+ParamType->getPointeeType(), RefExpr.get()->getValueKind(),
+RefExpr.get()->getExprLoc(), RefExpr.get(), VD, /*Index=*/0,
+/*PackIndex=*/std::nullopt,
+/*RefParam=*/true);
+  }
+}
   }
 
   // At this point we should have the right value category.
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index c3815bca038554..e93f7bd842e444 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2639,7 +2639,8 @@ static bool isSameTemplateArg(ASTContext ,
 /// argument.
 TemplateArgumentLoc
 

[clang] [Clang][Sema] Fix a bug on template partial specialization with issue on deduction of nontype tempalte parameter (PR #90376)

2024-04-28 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

Windows CI failed with an unrelated file.

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


[clang] [Clang][Sema] Fix a bug on template partial specialization with issue on deduction of nontype tempalte parameter (PR #90376)

2024-04-28 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/90376

>From f28eba548ae942ab3e567e7b2550a461e8fd5eac Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sun, 28 Apr 2024 14:24:30 +0800
Subject: [PATCH] [Clang][Sema] Fix a bug on template partial specialization
 with issue on deduction of nontype tempalte parameter

---
 clang/docs/ReleaseNotes.rst  |  2 ++
 clang/include/clang/Sema/Sema.h  | 10 ++
 clang/lib/Sema/SemaTemplate.cpp  | 18 ++
 clang/lib/Sema/SemaTemplateDeduction.cpp | 10 ++
 clang/test/SemaCXX/PR68885.cpp   | 21 +
 5 files changed, 49 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR68885.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a1390d6536b28c..8c1ba2a50b921b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -588,6 +588,8 @@ Bug Fixes to C++ Support
 - Fixed a use-after-free bug in parsing of type constraints with default 
arguments that involve lambdas. (#GH67235)
 - Fixed bug in which the body of a consteval lambda within a template was not 
parsed as within an
   immediate function context.
+- Fix a bug on template partial specialization with issue on deduction of 
nontype tempalte parameter
+  whose type is `decltype(auto)`. Fixes (#GH68885).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1ca523ec88c2f9..809b9c4498f697 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9249,7 +9249,8 @@ class Sema final : public SemaBase {
   void NoteTemplateParameterLocation(const NamedDecl );
 
   ExprResult BuildExpressionFromDeclTemplateArgument(
-  const TemplateArgument , QualType ParamType, SourceLocation Loc);
+  const TemplateArgument , QualType ParamType, SourceLocation Loc,
+  NamedDecl *TemplateParam = nullptr);
   ExprResult
   BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument ,
  SourceLocation Loc);
@@ -9572,9 +9573,10 @@ class Sema final : public SemaBase {
 
   bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg);
 
-  TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument 
,
-QualType NTTPType,
-SourceLocation Loc);
+  TemplateArgumentLoc
+  getTrivialTemplateArgumentLoc(const TemplateArgument , QualType NTTPType,
+SourceLocation Loc,
+NamedDecl *TemplateParam = nullptr);
 
   /// Get a template argument mapping the given template parameter to itself,
   /// e.g. for X in \c template, this would return an expression 
template
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index bbcb7c33a98579..6e5f7bd61a03a2 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8438,10 +8438,9 @@ void Sema::NoteTemplateParameterLocation(const NamedDecl 
) {
 /// declaration and the type of its corresponding non-type template
 /// parameter, produce an expression that properly refers to that
 /// declaration.
-ExprResult
-Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument ,
-  QualType ParamType,
-  SourceLocation Loc) {
+ExprResult Sema::BuildExpressionFromDeclTemplateArgument(
+const TemplateArgument , QualType ParamType, SourceLocation Loc,
+NamedDecl *TemplateParam) {
   // C++ [temp.param]p8:
   //
   //   A non-type template-parameter of type "array of T" or
@@ -8508,6 +8507,17 @@ Sema::BuildExpressionFromDeclTemplateArgument(const 
TemplateArgument ,
   } else {
 assert(ParamType->isReferenceType() &&
"unexpected type for decl template argument");
+if (NonTypeTemplateParmDecl *NTTP =
+dyn_cast_if_present(TemplateParam)) {
+  QualType TemplateParamType = NTTP->getType();
+  const AutoType *AT = TemplateParamType->getAs();
+  if (AT && AT->isDecltypeAuto()) {
+RefExpr = new (getASTContext()) SubstNonTypeTemplateParmExpr(
+ParamType->getPointeeType(), RefExpr.get()->getValueKind(),
+RefExpr.get()->getExprLoc(), RefExpr.get(), VD, 0, std::nullopt,
+true);
+  }
+}
   }
 
   // At this point we should have the right value category.
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index c3815bca038554..e93f7bd842e444 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2639,7 +2639,8 @@ static bool isSameTemplateArg(ASTContext ,
 /// argument.
 TemplateArgumentLoc
 Sema::getTrivialTemplateArgumentLoc(const TemplateArgument ,
-   

[clang] [Clang][Sema] Fix a bug on template partial specialization with issue on deduction of nontype tempalte parameter (PR #90376)

2024-04-28 Thread Qizhi Hu via cfe-commits

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


[clang] [Clang][Sema] Fix a bug on template partial specialization with issue on deduction of nontype tempalte parameter (PR #90376)

2024-04-28 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/90376

>From 641f3e695c4bf7cd67e9aff0e0d345b59ad88685 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sun, 28 Apr 2024 14:24:30 +0800
Subject: [PATCH] [Clang][Sema] Fix a bug on template partial specialization
 with issue on deduction of nontype tempalte parameter

---
 clang/docs/ReleaseNotes.rst  |  2 ++
 clang/include/clang/Sema/Sema.h  | 10 ++
 clang/lib/Sema/SemaTemplate.cpp  | 18 ++
 clang/lib/Sema/SemaTemplateDeduction.cpp | 10 ++
 clang/test/SemaCXX/PR68885.cpp   | 21 +
 5 files changed, 49 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR68885.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a1390d6536b28c..8c1ba2a50b921b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -588,6 +588,8 @@ Bug Fixes to C++ Support
 - Fixed a use-after-free bug in parsing of type constraints with default 
arguments that involve lambdas. (#GH67235)
 - Fixed bug in which the body of a consteval lambda within a template was not 
parsed as within an
   immediate function context.
+- Fix a bug on template partial specialization with issue on deduction of 
nontype tempalte parameter
+  whose type is `decltype(auto)`. Fixes (#GH68885).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1ca523ec88c2f9..809b9c4498f697 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9249,7 +9249,8 @@ class Sema final : public SemaBase {
   void NoteTemplateParameterLocation(const NamedDecl );
 
   ExprResult BuildExpressionFromDeclTemplateArgument(
-  const TemplateArgument , QualType ParamType, SourceLocation Loc);
+  const TemplateArgument , QualType ParamType, SourceLocation Loc,
+  NamedDecl *TemplateParam = nullptr);
   ExprResult
   BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument ,
  SourceLocation Loc);
@@ -9572,9 +9573,10 @@ class Sema final : public SemaBase {
 
   bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg);
 
-  TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument 
,
-QualType NTTPType,
-SourceLocation Loc);
+  TemplateArgumentLoc
+  getTrivialTemplateArgumentLoc(const TemplateArgument , QualType NTTPType,
+SourceLocation Loc,
+NamedDecl *TemplateParam = nullptr);
 
   /// Get a template argument mapping the given template parameter to itself,
   /// e.g. for X in \c template, this would return an expression 
template
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index bbcb7c33a98579..5425d862a06c82 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8438,10 +8438,9 @@ void Sema::NoteTemplateParameterLocation(const NamedDecl 
) {
 /// declaration and the type of its corresponding non-type template
 /// parameter, produce an expression that properly refers to that
 /// declaration.
-ExprResult
-Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument ,
-  QualType ParamType,
-  SourceLocation Loc) {
+ExprResult Sema::BuildExpressionFromDeclTemplateArgument(
+const TemplateArgument , QualType ParamType, SourceLocation Loc,
+NamedDecl *TemplateParam) {
   // C++ [temp.param]p8:
   //
   //   A non-type template-parameter of type "array of T" or
@@ -8508,6 +8507,17 @@ Sema::BuildExpressionFromDeclTemplateArgument(const 
TemplateArgument ,
   } else {
 assert(ParamType->isReferenceType() &&
"unexpected type for decl template argument");
+  if (NonTypeTemplateParmDecl *NTTP =
+  dyn_cast_if_present(TemplateParam)) {
+QualType TemplateParamType = NTTP->getType();
+const AutoType *AT = TemplateParamType->getAs();
+if (AT && AT->isDecltypeAuto()) {
+RefExpr = new (getASTContext()) SubstNonTypeTemplateParmExpr(
+ParamType->getPointeeType(), RefExpr.get()->getValueKind(),
+RefExpr.get()->getExprLoc(), RefExpr.get(), VD, 0, std::nullopt,
+true);
+}
+  }
   }
 
   // At this point we should have the right value category.
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index c3815bca038554..e93f7bd842e444 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2639,7 +2639,8 @@ static bool isSameTemplateArg(ASTContext ,
 /// argument.
 TemplateArgumentLoc
 Sema::getTrivialTemplateArgumentLoc(const TemplateArgument ,
- 

[clang] [Clang][Sema] Fix a bug on template partial specialization with issue on deduction of nontype tempalte parameter (PR #90376)

2024-04-28 Thread Qizhi Hu via cfe-commits


@@ -8508,6 +8507,16 @@ Sema::BuildExpressionFromDeclTemplateArgument(const 
TemplateArgument ,
   } else {
 assert(ParamType->isReferenceType() &&
"unexpected type for decl template argument");
+if (ParamType->isLValueReferenceType())
+  if (NonTypeTemplateParmDecl *NTTP =
+  dyn_cast_if_present(TemplateParam)) {
+QualType TemplateParamType = NTTP->getType();
+const AutoType *AT = TemplateParamType->getAs();
+if (AT && AT->isDecltypeAuto())
+  RefExpr = new (getASTContext())
+  ParenExpr(RefExpr.get()->getBeginLoc(),

jcsxky wrote:

Ah, thanks for your remind! `SubstNonTypeTemplateParmExpr` is more suitable 
here.

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


[clang] [Clang][Sema] Fix a bug on template partial specialization with issue on deduction of nontype tempalte parameter (PR #90376)

2024-04-28 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky created 
https://github.com/llvm/llvm-project/pull/90376

Fix https://github.com/llvm/llvm-project/issues/68885
When build expression from a deduced argument whose kind is `Declaration` and 
`NTTPType`(which declared as `decltype(auto)`) is deduced as a reference type, 
`BuildExpressionFromDeclTemplateArgument` just create a `DeclRef`. This is 
incorrect while we get type from the expression since we can't get the original 
reference type from `DeclRef`. Creating a `ParenExpr` expression and make the 
deduction correct. `ParenExpr` expression just helps the deduction and may not 
be same with the original expression.

>From 44d96874e8c2b905843166c08a8a002daa6ee99d Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sun, 28 Apr 2024 14:24:30 +0800
Subject: [PATCH] [Clang][Sema] Fix a bug on template partial specialization
 with issue on deduction of nontype tempalte parameter

---
 clang/docs/ReleaseNotes.rst  |  2 ++
 clang/include/clang/Sema/Sema.h  | 10 ++
 clang/lib/Sema/SemaTemplate.cpp  | 17 +
 clang/lib/Sema/SemaTemplateDeduction.cpp | 10 ++
 clang/test/SemaCXX/PR68885.cpp   | 21 +
 5 files changed, 48 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/SemaCXX/PR68885.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a1390d6536b28c..8c1ba2a50b921b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -588,6 +588,8 @@ Bug Fixes to C++ Support
 - Fixed a use-after-free bug in parsing of type constraints with default 
arguments that involve lambdas. (#GH67235)
 - Fixed bug in which the body of a consteval lambda within a template was not 
parsed as within an
   immediate function context.
+- Fix a bug on template partial specialization with issue on deduction of 
nontype tempalte parameter
+  whose type is `decltype(auto)`. Fixes (#GH68885).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1ca523ec88c2f9..809b9c4498f697 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9249,7 +9249,8 @@ class Sema final : public SemaBase {
   void NoteTemplateParameterLocation(const NamedDecl );
 
   ExprResult BuildExpressionFromDeclTemplateArgument(
-  const TemplateArgument , QualType ParamType, SourceLocation Loc);
+  const TemplateArgument , QualType ParamType, SourceLocation Loc,
+  NamedDecl *TemplateParam = nullptr);
   ExprResult
   BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument ,
  SourceLocation Loc);
@@ -9572,9 +9573,10 @@ class Sema final : public SemaBase {
 
   bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg);
 
-  TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument 
,
-QualType NTTPType,
-SourceLocation Loc);
+  TemplateArgumentLoc
+  getTrivialTemplateArgumentLoc(const TemplateArgument , QualType NTTPType,
+SourceLocation Loc,
+NamedDecl *TemplateParam = nullptr);
 
   /// Get a template argument mapping the given template parameter to itself,
   /// e.g. for X in \c template, this would return an expression 
template
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index bbcb7c33a98579..6a2f025521ce8e 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8438,10 +8438,9 @@ void Sema::NoteTemplateParameterLocation(const NamedDecl 
) {
 /// declaration and the type of its corresponding non-type template
 /// parameter, produce an expression that properly refers to that
 /// declaration.
-ExprResult
-Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument ,
-  QualType ParamType,
-  SourceLocation Loc) {
+ExprResult Sema::BuildExpressionFromDeclTemplateArgument(
+const TemplateArgument , QualType ParamType, SourceLocation Loc,
+NamedDecl *TemplateParam) {
   // C++ [temp.param]p8:
   //
   //   A non-type template-parameter of type "array of T" or
@@ -8508,6 +8507,16 @@ Sema::BuildExpressionFromDeclTemplateArgument(const 
TemplateArgument ,
   } else {
 assert(ParamType->isReferenceType() &&
"unexpected type for decl template argument");
+if (ParamType->isLValueReferenceType())
+  if (NonTypeTemplateParmDecl *NTTP =
+  dyn_cast_if_present(TemplateParam)) {
+QualType TemplateParamType = NTTP->getType();
+const AutoType *AT = TemplateParamType->getAs();
+if (AT && AT->isDecltypeAuto())
+  RefExpr = new (getASTContext())
+  ParenExpr(RefExpr.get()->getBeginLoc(),
+  

[clang] [Clang][Sema] fix a bug on template partial specialization (PR #89862)

2024-04-25 Thread Qizhi Hu via cfe-commits


@@ -7706,7 +7706,7 @@ ExprResult 
Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
 // FIXME: The language rules don't say what happens in this case.
 // FIXME: We get an opaque dependent type out of decltype(auto) if the
 // expression is merely instantiation-dependent; is this enough?
-if (CTAK == CTAK_Deduced && Arg->isTypeDependent()) {
+if (Arg->isTypeDependent()) {

jcsxky wrote:

After looking into the code a bit more, I think this won't happen since the 
type of `Arg` can't be dependent if the condition `CTAK == 
CTAK_DeducedFromArrayBound` holds. Because it has been deduced as a certain 
expression at the moment.

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


[clang] [Clang][Sema] fix a bug on template partial specialization (PR #89862)

2024-04-23 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky created 
https://github.com/llvm/llvm-project/pull/89862

attempt to fix 
https://github.com/llvm/llvm-project/issues/68885#issuecomment-1764201896
Deduction of NTTP whose type is `decltype(auto)` would create an implicit cast 
expression to dependent type and makes the type of primary template definition 
(`InjectedClassNameSpecialization`) and its partial specialization different. 
Prevent emitting cast expression to make clang knows their types are identical 
by removing `CTAK == CTAK_Deduced` when the type is `decltype(auto)`.

>From 9b3e69844033a99be0eef90e816b9dff3e64c901 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Wed, 24 Apr 2024 09:37:53 +0800
Subject: [PATCH] [Clang][Sema] fix a bug on template partial specialization

---
 clang/docs/ReleaseNotes.rst |  1 +
 clang/lib/Sema/SemaTemplate.cpp |  2 +-
 ...dentical-type-primary-partial-specialization.cpp | 13 +
 3 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 
clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3db558a1c11a3f..27341fb0e3a772 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -561,6 +561,7 @@ Bug Fixes to C++ Support
 - Fixed a crash when trying to evaluate a user-defined ``static_assert`` 
message whose ``size()``
   function returns a large or negative value. Fixes (#GH89407).
 - Fixed a use-after-free bug in parsing of type constraints with default 
arguments that involve lambdas. (#GH67235)
+- Fix a bug on template partial specialization whose template parameter is 
`decltype(auto)`.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 4bda31ba67c02d..345d77849b49d0 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7706,7 +7706,7 @@ ExprResult 
Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
 // FIXME: The language rules don't say what happens in this case.
 // FIXME: We get an opaque dependent type out of decltype(auto) if the
 // expression is merely instantiation-dependent; is this enough?
-if (CTAK == CTAK_Deduced && Arg->isTypeDependent()) {
+if (Arg->isTypeDependent()) {
   auto *AT = dyn_cast(DeducedT);
   if (AT && AT->isDecltypeAuto()) {
 SugaredConverted = TemplateArgument(Arg);
diff --git 
a/clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp 
b/clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp
new file mode 100644
index 00..ad51ca8252ef50
--- /dev/null
+++ b/clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+template 
+struct S { // expected-note {{previous definition is here}}
+static constexpr int i = 42;
+};
+
+template 
+struct S { // expected-error {{class template partial specialization does 
not specialize any template argument; to define the primary template, remove 
the template argument list}} \
+  // expected-error {{redefinition of 'S'}}
+static constexpr int i = 0;
+};

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


[clang] [Clang][Sema] set declaration invalid earlier to prevent crash in calculating record layout (PR #87173)

2024-04-17 Thread Qizhi Hu via cfe-commits

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


[clang] [Clang][Sema] set declaration invalid earlier to prevent crash in calculating record layout (PR #87173)

2024-04-17 Thread Qizhi Hu via cfe-commits

https://github.com/jcsxky updated 
https://github.com/llvm/llvm-project/pull/87173

>From 19b2cab0c84a934910f65536a0627045d30b9729 Mon Sep 17 00:00:00 2001
From: huqizhi 
Date: Sun, 31 Mar 2024 09:38:05 +0800
Subject: [PATCH] [Clang][Sema] set declaration invalid earlier to prevent
 crash in calculating record layout

---
 clang/docs/ReleaseNotes.rst  | 2 ++
 clang/include/clang/Sema/Scope.h | 6 ++
 clang/lib/Parse/ParseDeclCXX.cpp | 5 +
 clang/lib/Sema/SemaDecl.cpp  | 7 +++
 clang/test/SemaCXX/PR75221.cpp   | 6 ++
 5 files changed, 26 insertions(+)
 create mode 100644 clang/test/SemaCXX/PR75221.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c19ad9fba58f37..6c51c2d1f483ce 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -536,6 +536,8 @@ Bug Fixes to C++ Support
   Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), 
(#GH86398), and (#GH86399).
 - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329).
 - Fix a crash in requires expression with templated base class member 
function. Fixes (#GH84020).
+- Fix a crash caused by defined struct in a type alias template when the 
structure
+  has fields with dependent type. Fixes (#GH75221).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 099c2739e8603a..1752a25111a775 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -156,6 +156,9 @@ class Scope {
 /// This is the scope of an OpenACC Compute Construct, which restricts
 /// jumping into/out of it.
 OpenACCComputeConstructScope = 0x1000,
+
+/// This is a scope of type alias declaration.
+TypeAliasScope = 0x2000,
   };
 
 private:
@@ -580,6 +583,9 @@ class Scope {
   /// if/switch/while/for statement.
   bool isControlScope() const { return getFlags() & Scope::ControlScope; }
 
+  /// Determine whether this scope is a type alias scope.
+  bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; }
+
   /// Returns if rhs has a higher scope depth than this.
   ///
   /// The caller is responsible for calling this only if one of the two scopes
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 51fd64b2d01aa7..8e0e8682482933 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -799,6 +799,11 @@ Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(
 ProhibitAttributes(PrefixAttrs);
 
 Decl *DeclFromDeclSpec = nullptr;
+Scope *CurScope = getCurScope();
+if (CurScope)
+  CurScope->setFlags(Scope::ScopeFlags::TypeAliasScope |
+ CurScope->getFlags());
+
 Decl *AD = ParseAliasDeclarationAfterDeclarator(
 TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, );
 return Actions.ConvertDeclToDeclGroup(AD, DeclFromDeclSpec);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1bde99d6fce740..356abe09a5ca62 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -19529,6 +19529,13 @@ void Sema::ActOnFields(Scope *S, SourceLocation 
RecLoc, Decl *EnclosingDecl,
   // Okay, we successfully defined 'Record'.
   if (Record) {
 bool Completed = false;
+if (S) {
+  Scope *Parent = S->getParent();
+  if (Parent && Parent->isTypeAliasScope() &&
+  Parent->isTemplateParamScope())
+Record->setInvalidDecl();
+}
+
 if (CXXRecord) {
   if (!CXXRecord->isInvalidDecl()) {
 // Set access bits correctly on the directly-declared conversions.
diff --git a/clang/test/SemaCXX/PR75221.cpp b/clang/test/SemaCXX/PR75221.cpp
new file mode 100644
index 00..b342e347c5606a
--- /dev/null
+++ b/clang/test/SemaCXX/PR75221.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -verify -std=c++11 -fsyntax-only %s
+
+template  using foo = struct foo { // expected-error {{'foo' cannot 
be defined in a type alias template}}
+  T size = 0;
+};
+foo a;

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


[clang] [Clang][Sema] set declaration invalid earlier to prevent crash in calculating record layout (PR #87173)

2024-04-17 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

gently ping. @erichkeane @shafik Any opinions on this pr?

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


  1   2   3   4   5   >