[clang] [clang]Transform uninstantiated ExceptionSpec in `TemplateInstantiator` (PR #77073)
Congcong Cai via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 5 02:16:15 PST 2024
https://github.com/HerrCai0907 created https://github.com/llvm/llvm-project/pull/77073
Fixes: #77071
`SubstituteDeducedTypeTransform` will transform type and it will visit uninstantiated `ExceptionSpecInfo`, which will cause odd behavior
>From 04ef8fd566491024c8163ad3b901f8c4cebaf890 Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Fri, 5 Jan 2024 18:15:24 +0800
Subject: [PATCH] [clang]Transform uninstantiated ExceptionSpec in
TemplateInstantiator
Fixes: #77071
SubstituteDeducedTypeTransform will transform type and it will visit uninstantiated ExceptionSpecInfo which will odd behavior
---
clang/docs/ReleaseNotes.rst | 3 ++-
clang/include/clang/AST/Type.h | 2 ++
clang/lib/AST/Type.cpp | 7 +++++++
clang/lib/Sema/SemaTemplateDeduction.cpp | 11 +++++++++++
clang/lib/Sema/SemaTemplateInstantiate.cpp | 4 +---
.../SemaCXX/dependent-noexcept-uninstantiated.cpp | 4 +++-
6 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ee211c16a48ac8..f750587ad12271 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -607,7 +607,8 @@ Bug Fixes in This Version
- Clang will correctly evaluate ``noexcept`` expression for template functions
of template classes. Fixes
(`#68543 <https://github.com/llvm/llvm-project/issues/68543>`_,
- `#42496 <https://github.com/llvm/llvm-project/issues/42496>`_)
+ `#42496 <https://github.com/llvm/llvm-project/issues/42496>`_,
+ `#77071 <https://github.com/llvm/llvm-project/issues/77071>`_)
- Fixed an issue when a shift count larger than ``__INT64_MAX__``, in a right
shift operation, could result in missing warnings about
``shift count >= width of type`` or internal compiler error.
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index b3ae66e6e769d0..0fcf331dd79bc6 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -4228,6 +4228,8 @@ class FunctionProtoType final
ExceptionSpecInfo() = default;
ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {}
+
+ void instantiate();
};
/// Extra information about a function prototype. ExtProtoInfo is not
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 160a725939ccd4..a894d3289eb185 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -3414,6 +3414,13 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
llvm_unreachable("Invalid calling convention.");
}
+void FunctionProtoType::ExceptionSpecInfo::instantiate() {
+ assert(Type == EST_Uninstantiated);
+ NoexceptExpr =
+ cast<FunctionProtoType>(SourceTemplate->getType())->getNoexceptExpr();
+ Type = EST_DependentNoexcept;
+}
+
FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
QualType canonical,
const ExtProtoInfo &epi)
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 699e0985e595b6..015b0abaf0e5ee 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4737,6 +4737,7 @@ namespace {
QualType Replacement;
bool ReplacementIsPack;
bool UseTypeSugar;
+ using inherited = TreeTransform<SubstituteDeducedTypeTransform>;
public:
SubstituteDeducedTypeTransform(Sema &SemaRef, DependentAuto DA)
@@ -4797,6 +4798,16 @@ namespace {
// Lambdas never need to be transformed.
return E;
}
+ bool TransformExceptionSpec(SourceLocation Loc,
+ FunctionProtoType::ExceptionSpecInfo &ESI,
+ SmallVectorImpl<QualType> &Exceptions,
+ bool &Changed) {
+ if (ESI.Type == EST_Uninstantiated) {
+ ESI.instantiate();
+ Changed = true;
+ }
+ return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);
+ }
QualType Apply(TypeLoc TL) {
// Create some scratch storage for the transformed type locations.
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index df6b40999e645c..2c452404459a5d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1630,9 +1630,7 @@ bool TemplateInstantiator::TransformExceptionSpec(
SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
if (ESI.Type == EST_Uninstantiated) {
- ESI.NoexceptExpr = cast<FunctionProtoType>(ESI.SourceTemplate->getType())
- ->getNoexceptExpr();
- ESI.Type = EST_DependentNoexcept;
+ ESI.instantiate();
Changed = true;
}
return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);
diff --git a/clang/test/SemaCXX/dependent-noexcept-uninstantiated.cpp b/clang/test/SemaCXX/dependent-noexcept-uninstantiated.cpp
index ddb26989022753..3821f18e7bf276 100644
--- a/clang/test/SemaCXX/dependent-noexcept-uninstantiated.cpp
+++ b/clang/test/SemaCXX/dependent-noexcept-uninstantiated.cpp
@@ -6,6 +6,8 @@ using B = char;
template <class T> struct C {
template <class V> void f0() noexcept(sizeof(T) == sizeof(A) && sizeof(V) == sizeof(B)) {}
+ template <class V> auto f1(V a) noexcept(1) {return a;}
};
-void (C<int>::*tmp1)() noexcept = &C<A>::f0<B>;
+void (C<int>::*tmp0)() noexcept = &C<A>::f0<B>;
+int (C<int>::*tmp1)(int) noexcept = &C<A>::f1;
More information about the cfe-commits
mailing list