Skip to content

Commit 9f3e340

Browse files
authored
[clang]Transform uninstantiated ExceptionSpec in TemplateInstantiator (llvm#68878)
Fixes llvm#68543, llvm#42496
1 parent 7c651a1 commit 9f3e340

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,10 @@ Bug Fixes in This Version
474474
cannot be used with ``Release`` mode builds. (`#68237 <https://github.com/llvm/llvm-project/issues/68237>`_).
475475
- Fix crash in evaluating ``constexpr`` value for invalid template function.
476476
Fixes (`#68542 <https://github.com/llvm/llvm-project/issues/68542>`_)
477+
- Clang will correctly evaluate ``noexcept`` expression for template functions
478+
of template classes. Fixes
479+
(`#68543 <https://github.com/llvm/llvm-project/issues/68543>`_,
480+
`#42496 <https://github.com/llvm/llvm-project/issues/42496>`_)
477481
- Fixed an issue when a shift count larger than ``__INT64_MAX__``, in a right
478482
shift operation, could result in missing warnings about
479483
``shift count >= width of type`` or internal compiler error.

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3367,7 +3367,14 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
33673367
SmallVector<QualType, 4> ExceptionStorage;
33683368
if (getLangOpts().CPlusPlus17 &&
33693369
SubstExceptionSpec(Function->getLocation(), EPI.ExceptionSpec,
3370-
ExceptionStorage, MLTAL))
3370+
ExceptionStorage,
3371+
getTemplateInstantiationArgs(
3372+
FunctionTemplate, nullptr, /*Final=*/true,
3373+
/*Innermost=*/SugaredExplicitArgumentList,
3374+
/*RelativeToPrimary=*/false,
3375+
/*Pattern=*/nullptr,
3376+
/*ForConstraintInstantiation=*/false,
3377+
/*SkipForSpecialization=*/true)))
33713378
return TDK_SubstitutionFailure;
33723379

33733380
*FunctionType = BuildFunctionType(ResultType, ParamTypes,

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,11 @@ namespace {
13351335
/// declaration.
13361336
NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc);
13371337

1338+
bool TransformExceptionSpec(SourceLocation Loc,
1339+
FunctionProtoType::ExceptionSpecInfo &ESI,
1340+
SmallVectorImpl<QualType> &Exceptions,
1341+
bool &Changed);
1342+
13381343
/// Rebuild the exception declaration and register the declaration
13391344
/// as an instantiated local.
13401345
VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
@@ -1617,6 +1622,18 @@ Decl *TemplateInstantiator::TransformDefinition(SourceLocation Loc, Decl *D) {
16171622
return Inst;
16181623
}
16191624

1625+
bool TemplateInstantiator::TransformExceptionSpec(
1626+
SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
1627+
SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
1628+
if (ESI.Type == EST_Uninstantiated) {
1629+
ESI.NoexceptExpr = cast<FunctionProtoType>(ESI.SourceTemplate->getType())
1630+
->getNoexceptExpr();
1631+
ESI.Type = EST_DependentNoexcept;
1632+
Changed = true;
1633+
}
1634+
return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);
1635+
}
1636+
16201637
NamedDecl *
16211638
TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,
16221639
SourceLocation Loc) {
@@ -2684,8 +2701,6 @@ bool Sema::SubstExceptionSpec(SourceLocation Loc,
26842701
FunctionProtoType::ExceptionSpecInfo &ESI,
26852702
SmallVectorImpl<QualType> &ExceptionStorage,
26862703
const MultiLevelTemplateArgumentList &Args) {
2687-
assert(ESI.Type != EST_Uninstantiated);
2688-
26892704
bool Changed = false;
26902705
TemplateInstantiator Instantiator(*this, Args, Loc, DeclarationName());
26912706
return Instantiator.TransformExceptionSpec(Loc, ESI, ExceptionStorage,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 -fsyntax-only -std=c++17 %s
2+
// expected-no-diagnostics
3+
4+
using A = int;
5+
using B = char;
6+
7+
template <class T> struct C {
8+
template <class V> void f0() noexcept(sizeof(T) == sizeof(A) && sizeof(V) == sizeof(B)) {}
9+
};
10+
11+
void (C<int>::*tmp1)() noexcept = &C<A>::f0<B>;

0 commit comments

Comments
 (0)