diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 439e47b209b2f..20e5a33ff7711 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -513,6 +513,8 @@ Bug Fixes to Attribute Support - Fix handling of parameter indexes when an attribute is applied to a C++23 explicit object member function. - Fixed several false positives and false negatives in function effect (`nonblocking`) analysis. (#GH166078) (#GH166101) (#GH166110) - Fix ``cleanup`` attribute by delaying type checks until after the type is deduced. (#GH129631) +- Fix a crash when instantiating a function template with ``constructor`` or ``destructor`` + attributes without a priority argument. (#GH169072) Bug Fixes to C++ Support ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 26693514bb278..e74c41517ecbf 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -245,15 +245,17 @@ static void sharedInstantiateConstructorDestructorAttr( ExprResult Result = S.SubstExpr(A->getPriority(), TemplateArgs); if (Result.isInvalid()) return; - tempInstPriority = Result.get(); - if (std::optional CE = - tempInstPriority->getIntegerConstantExpr(C)) { - // Consistent with non-templated priority arguments, which must fit in a - // 32-bit unsigned integer. - if (!CE->isIntN(32)) { - S.Diag(tempInstPriority->getExprLoc(), diag::err_ice_too_large) - << toString(*CE, 10, false) << /*Size=*/32 << /*Unsigned=*/1; - return; + if (Result.isUsable()) { + tempInstPriority = Result.get(); + if (std::optional CE = + tempInstPriority->getIntegerConstantExpr(C)) { + // Consistent with non-templated priority arguments, which must fit in a + // 32-bit unsigned integer. + if (!CE->isIntN(32)) { + S.Diag(tempInstPriority->getExprLoc(), diag::err_ice_too_large) + << toString(*CE, 10, false) << /*Size=*/32 << /*Unsigned=*/1; + return; + } } } } diff --git a/clang/test/SemaTemplate/attributes.cpp b/clang/test/SemaTemplate/attributes.cpp index 20fe983af28f7..d0ab0a68dec2a 100644 --- a/clang/test/SemaTemplate/attributes.cpp +++ b/clang/test/SemaTemplate/attributes.cpp @@ -640,3 +640,23 @@ namespace preferred_name { Foo<1, 2, int, float>::nosuch x; // expected-error {{no type named 'nosuch' in 'preferred_name::Bar'}} } ::preferred_name::Foo<1, 2, int, float>::nosuch x; // expected-error {{no type named 'nosuch' in 'preferred_name::Bar'}} + +// GH169072: templated attribute((constructor)) function crashes clang +// constructor/destructor attribute without priority argument should not crash. +namespace gh169072 { + template + [[gnu::constructor]] void foo() {} + + template void foo(); + + template + [[gnu::destructor]] void bar() {} + + template void bar(); + + // Also test with explicit priority argument + template + [[gnu::constructor(101)]] void baz() {} + + template void baz(); +}