https://github.com/oToToT updated 
https://github.com/llvm/llvm-project/pull/182752

>From 46e80f1e2e6770b3a5949dd6061a7d9d23e1e23a Mon Sep 17 00:00:00 2001
From: Tommy Chiang <[email protected]>
Date: Sun, 22 Feb 2026 23:59:04 +0800
Subject: [PATCH] [Sema] Guard transformed loop-hint expression before use

TransformLoopHintAttr called TransformExpr(...).get() without checking
that the transformed expression was usable.

For `#pragma GCC unroll v()` instantiated with `v = int`, expression
transformation fails and Clang can assert while validating the loop hint.

Check ExprResult::isUsable() before calling get() and keep the original
attribute on failure.

Fixes https://github.com/llvm/llvm-project/issues/49502
---
 clang/lib/Sema/SemaTemplateInstantiate.cpp      |  6 +++++-
 clang/test/Sema/unroll-template-value-crash.cpp | 11 ++++++++++-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 37309d057fbe7..35e2a49efd9da 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2166,7 +2166,11 @@ TemplateInstantiator::TransformCXXAssumeAttr(const 
CXXAssumeAttr *AA) {
 
 const LoopHintAttr *
 TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) {
-  Expr *TransformedExpr = getDerived().TransformExpr(LH->getValue()).get();
+  ExprResult TransformedExprResult = 
getDerived().TransformExpr(LH->getValue());
+  if (!TransformedExprResult.isUsable())
+    return LH;
+
+  Expr *TransformedExpr = TransformedExprResult.get();
 
   if (TransformedExpr == LH->getValue())
     return LH;
diff --git a/clang/test/Sema/unroll-template-value-crash.cpp 
b/clang/test/Sema/unroll-template-value-crash.cpp
index cda4b897509b9..d9cb2601e045c 100644
--- a/clang/test/Sema/unroll-template-value-crash.cpp
+++ b/clang/test/Sema/unroll-template-value-crash.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -x c++ -verify %s
-// expected-no-diagnostics
 
 template <int Unroll> void foo() {
   #pragma unroll Unroll
@@ -33,3 +32,13 @@ void use(T t) {
 void test() {
   use(val());
 }
+
+template <typename T> void pr49502(T v) {
+#pragma GCC unroll v() // expected-error {{called object type 'int' is not a 
function or function pointer}}
+  for (;;) {
+  }
+}
+
+void pr49502_caller() {
+  pr49502(0); // expected-note {{in instantiation of function template 
specialization 'pr49502<int>' requested here}}
+}

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

Reply via email to