Author: Congcong Cai Date: 2024-01-05T23:37:58+08:00 New Revision: de5039545ee4e9f5aa7023632d5c4baa5e782e51
URL: https://github.com/llvm/llvm-project/commit/de5039545ee4e9f5aa7023632d5c4baa5e782e51 DIFF: https://github.com/llvm/llvm-project/commit/de5039545ee4e9f5aa7023632d5c4baa5e782e51.diff LOG: [clang]Transform uninstantiated ExceptionSpec in `TemplateInstantiator` (#77073) Fixes: #77071 `SubstituteDeducedTypeTransform` will transform type and it will visit uninstantiated `ExceptionSpecInfo`, which will cause odd behavior. Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/AST/Type.h clang/lib/AST/Type.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/SemaCXX/dependent-noexcept-uninstantiated.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f5159cdc8a3bff..9b6e00b231216b 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 1afa693672860f..9e9f896ebef7a6 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -4224,6 +4224,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 27a4b68fd59ab9..09dd119ed1b948 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 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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits