Author: Carson Radtke
Date: 2025-11-28T15:26:43+08:00
New Revision: 1e7efca659cdf37a95e27e35fa002d340ea68b32

URL: 
https://github.com/llvm/llvm-project/commit/1e7efca659cdf37a95e27e35fa002d340ea68b32
DIFF: 
https://github.com/llvm/llvm-project/commit/1e7efca659cdf37a95e27e35fa002d340ea68b32.diff

LOG: [clang] fix crash when template with constructor attribute is instantiated 
without a priority (#169282)

fixes: https://github.com/llvm/llvm-project/issues/169072

The current implementation expects the priority argument to be provided
to `[[gnu::constructor(<priority>)]]`, but the argument is really
optional. This was causing a segfault when instantiating the
function-template because we were trying to fold an `Expr*` that was a
nullptr.

This change skips the evaluation of the priority argument when it is
missing; this will instantiate a function declaration with the default
priority (65535).

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/test/SemaTemplate/attributes.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4cfcd37df1866..da064534c25d9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -518,6 +518,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<llvm::APSInt> 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<llvm::APSInt> 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<int, float>'}}
 }
 ::preferred_name::Foo<1, 2, int, float>::nosuch x; // expected-error {{no type 
named 'nosuch' in 'preferred_name::Bar<int, float>'}}
+
+// GH169072: templated attribute((constructor)) function crashes clang
+// constructor/destructor attribute without priority argument should not crash.
+namespace gh169072 {
+  template <typename T>
+  [[gnu::constructor]] void foo() {}
+  
+  template void foo<int>();
+
+  template <typename T>
+  [[gnu::destructor]] void bar() {}
+  
+  template void bar<int>();
+
+  // Also test with explicit priority argument
+  template <typename T>
+  [[gnu::constructor(101)]] void baz() {}
+  
+  template void baz<int>();
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to