diff options
author | Congcong Cai <congcongcai0907@163.com> | 2024-01-05 23:37:58 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-05 23:37:58 +0800 |
commit | de5039545ee4e9f5aa7023632d5c4baa5e782e51 (patch) | |
tree | 9434b2f8718bc7b7d6bac6f828507557dc4b1859 | |
parent | 922b7b8bf465ddc292fa91bd6a860510a1eea6e2 (diff) |
[clang]Transform uninstantiated ExceptionSpec in `TemplateInstantiator` (#77073)
Fixes: #77071
`SubstituteDeducedTypeTransform` will transform type and it will visit
uninstantiated `ExceptionSpecInfo`, which will cause odd behavior.
-rw-r--r-- | clang/docs/ReleaseNotes.rst | 3 | ||||
-rw-r--r-- | clang/include/clang/AST/Type.h | 2 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 4 | ||||
-rw-r--r-- | clang/test/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 f5159cdc8a3b..9b6e00b23121 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -609,7 +609,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 1afa69367286..9e9f896ebef7 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -4224,6 +4224,8 @@ public: 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 160a725939cc..a894d3289eb1 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 699e0985e595..015b0abaf0e5 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 27a4b68fd59a..09dd119ed1b9 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1639,9 +1639,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 ddb269890227..3821f18e7bf2 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; |