Skip to content

Commit de50395

Browse files
authored
[clang]Transform uninstantiated ExceptionSpec in TemplateInstantiator (#77073)
Fixes: #77071 `SubstituteDeducedTypeTransform` will transform type and it will visit uninstantiated `ExceptionSpecInfo`, which will cause odd behavior.
1 parent 922b7b8 commit de50395

File tree

6 files changed

+26
-5
lines changed

6 files changed

+26
-5
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,8 @@ Bug Fixes in This Version
609609
- Clang will correctly evaluate ``noexcept`` expression for template functions
610610
of template classes. Fixes
611611
(`#68543 <https://github.com/llvm/llvm-project/issues/68543>`_,
612-
`#42496 <https://github.com/llvm/llvm-project/issues/42496>`_)
612+
`#42496 <https://github.com/llvm/llvm-project/issues/42496>`_,
613+
`#77071 <https://github.com/llvm/llvm-project/issues/77071>`_)
613614
- Fixed an issue when a shift count larger than ``__INT64_MAX__``, in a right
614615
shift operation, could result in missing warnings about
615616
``shift count >= width of type`` or internal compiler error.

clang/include/clang/AST/Type.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4224,6 +4224,8 @@ class FunctionProtoType final
42244224
ExceptionSpecInfo() = default;
42254225

42264226
ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {}
4227+
4228+
void instantiate();
42274229
};
42284230

42294231
/// Extra information about a function prototype. ExtProtoInfo is not

clang/lib/AST/Type.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3414,6 +3414,13 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
34143414
llvm_unreachable("Invalid calling convention.");
34153415
}
34163416

3417+
void FunctionProtoType::ExceptionSpecInfo::instantiate() {
3418+
assert(Type == EST_Uninstantiated);
3419+
NoexceptExpr =
3420+
cast<FunctionProtoType>(SourceTemplate->getType())->getNoexceptExpr();
3421+
Type = EST_DependentNoexcept;
3422+
}
3423+
34173424
FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
34183425
QualType canonical,
34193426
const ExtProtoInfo &epi)

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4737,6 +4737,7 @@ namespace {
47374737
QualType Replacement;
47384738
bool ReplacementIsPack;
47394739
bool UseTypeSugar;
4740+
using inherited = TreeTransform<SubstituteDeducedTypeTransform>;
47404741

47414742
public:
47424743
SubstituteDeducedTypeTransform(Sema &SemaRef, DependentAuto DA)
@@ -4797,6 +4798,16 @@ namespace {
47974798
// Lambdas never need to be transformed.
47984799
return E;
47994800
}
4801+
bool TransformExceptionSpec(SourceLocation Loc,
4802+
FunctionProtoType::ExceptionSpecInfo &ESI,
4803+
SmallVectorImpl<QualType> &Exceptions,
4804+
bool &Changed) {
4805+
if (ESI.Type == EST_Uninstantiated) {
4806+
ESI.instantiate();
4807+
Changed = true;
4808+
}
4809+
return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);
4810+
}
48004811

48014812
QualType Apply(TypeLoc TL) {
48024813
// Create some scratch storage for the transformed type locations.

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,9 +1639,7 @@ bool TemplateInstantiator::TransformExceptionSpec(
16391639
SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
16401640
SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
16411641
if (ESI.Type == EST_Uninstantiated) {
1642-
ESI.NoexceptExpr = cast<FunctionProtoType>(ESI.SourceTemplate->getType())
1643-
->getNoexceptExpr();
1644-
ESI.Type = EST_DependentNoexcept;
1642+
ESI.instantiate();
16451643
Changed = true;
16461644
}
16471645
return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);

clang/test/SemaCXX/dependent-noexcept-uninstantiated.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ using B = char;
66

77
template <class T> struct C {
88
template <class V> void f0() noexcept(sizeof(T) == sizeof(A) && sizeof(V) == sizeof(B)) {}
9+
template <class V> auto f1(V a) noexcept(1) {return a;}
910
};
1011

11-
void (C<int>::*tmp1)() noexcept = &C<A>::f0<B>;
12+
void (C<int>::*tmp0)() noexcept = &C<A>::f0<B>;
13+
int (C<int>::*tmp1)(int) noexcept = &C<A>::f1;

0 commit comments

Comments
 (0)