[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 via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 37eb9c9632fb5e82827d1a0559f2279e9a9f1969 
641f3e695c4bf7cd67e9aff0e0d345b59ad88685 -- clang/test/SemaCXX/PR68885.cpp 
clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaTemplate.cpp 
clang/lib/Sema/SemaTemplateDeduction.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 5425d862a0..6e5f7bd61a 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8507,17 +8507,17 @@ ExprResult 
Sema::BuildExpressionFromDeclTemplateArgument(
   } 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()) {
+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.

``




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 Younan Zhang 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(),

zyn0217 wrote:

Did you try to preserve the references using `SubstNonTypeTemplateParmExpr`s 
just like what @cor3ntin said? This looks a bit odd to me...

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 Vlad Serebrennikov via cfe-commits

https://github.com/Endilll commented:

`Sema.h` changes look good to me.

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 via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Qizhi Hu (jcsxky)


Changes

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.

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


5 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+2) 
- (modified) clang/include/clang/Sema/Sema.h (+6-4) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+13-4) 
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+6-4) 
- (added) clang/test/SemaCXX/PR68885.cpp (+21) 


``diff
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(),
+RefExpr.get()->getEndLoc(), RefExpr.get());
+  }
   }
 
   // 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
--- 

[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(),
+