[clang] de50395 - [clang]Transform uninstantiated ExceptionSpec in `TemplateInstantiator` (#77073)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 5 07:38:03 PST 2024


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;


        


More information about the cfe-commits mailing list