-
Notifications
You must be signed in to change notification settings - Fork 15k
Description
Bugzilla Link | 43151 |
Version | trunk |
OS | Linux |
Attachments | Small reproducer for the bug, compile with -std=c++17. |
CC | @AaronBallman,@riccibruno,@zygoloid |
Extended Description
Compiling the following code with -fsyntax-only -std=c++17
produces an assertion failure:
template<typename T>
struct X {
using self = X<T>;
template<bool noex>
void f() noexcept(noex)
{
auto x = &self::f<noex>;
}
};
void g()
{
X<int> x;
x.f<true>();
}
The trace shows:
1. <eof> parser at end of file
2. template-crash.cpp:6:8: instantiating function definition 'X<int>::f<true>'
The issue disappears when removing -std=c++17
, probably because the exception specification is not part of the type then.
The function is called from clang::Sema::SubstituteExplicitTemplateArguments
, where we have EPI.ExceptionSpec.Type = clang::EST_Uninstantiated
and EPI.ExceptionSpec.SourceDecl = Function
. On the other hand, the type of EPI.ExceptionSpec.SourceTemplate
has an ExceptionSpec
with Type = clang::EST_DependentNoexcept
. So it seems we should be passing that one to Sema::SubstExceptionSpec
instead.
Indeed, the following seems to fix the assertion (and not introduce new issues):
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3112,6 +3112,13 @@ Sema::SubstituteExplicitTemplateArguments(
// so substitution into the type must also substitute into the exception
// specification.
SmallVector<QualType, 4> ExceptionStorage;
+ if (EPI.ExceptionSpec.Type == EST_Uninstantiated) {
+ assert(Function == EPI.ExceptionSpec.SourceDecl);
+ const auto *TplType = EPI.ExceptionSpec.SourceTemplate->getType()
+ ->getAs<FunctionProtoType>();
+ EPI.ExceptionSpec = TplType->getExtProtoInfo().ExceptionSpec;
+ assert(EPI.ExceptionSpec.Type != EST_Uninstantiated);
+ }
if (getLangOpts().CPlusPlus17 &&
SubstExceptionSpec(
Function->getLocation(), EPI.ExceptionSpec, ExceptionStorage,
But this seems like a hack, since in other instances the ExceptionSpec
is already instantiated correctly.