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
