llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Bruno De Fraine (brunodf-snps) <details> <summary>Changes</summary> In cases where multiple template instations occur (e.g. with a generic lambda), the loop hint argument expression may still be value dependent. (It is also not needed to do the constant evaluation when the loop hint is not an unroll count anyway.) --- Full diff: https://github.com/llvm/llvm-project/pull/172289.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+11-7) - (modified) clang/test/Sema/unroll-template-value-crash.cpp (+25) ``````````diff diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 35205f40cbcef..dcbedb2c2ee22 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2197,19 +2197,23 @@ TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) { // Generate error if there is a problem with the value. if (getSema().CheckLoopHintExpr(TransformedExpr, LH->getLocation(), - LH->getSemanticSpelling() == + /*AllowZero=*/LH->getSemanticSpelling() == LoopHintAttr::Pragma_unroll)) return LH; LoopHintAttr::OptionType Option = LH->getOption(); LoopHintAttr::LoopHintState State = LH->getState(); - llvm::APSInt ValueAPS = - TransformedExpr->EvaluateKnownConstInt(getSema().getASTContext()); - // The values of 0 and 1 block any unrolling of the loop. - if (ValueAPS.isZero() || ValueAPS.isOne()) { - Option = LoopHintAttr::Unroll; - State = LoopHintAttr::Disable; + if (Option == LoopHintAttr::UnrollCount && + !TransformedExpr->isValueDependent()) { + llvm::APSInt ValueAPS = + TransformedExpr->EvaluateKnownConstInt(getSema().getASTContext()); + // The values of 0 and 1 block any unrolling of the loop (also see + // handleLoopHintAttr in SemaStmtAttr). + if (ValueAPS.isZero() || ValueAPS.isOne()) { + Option = LoopHintAttr::Unroll; + State = LoopHintAttr::Disable; + } } // Create new LoopHintValueAttr with integral expression in place of the diff --git a/clang/test/Sema/unroll-template-value-crash.cpp b/clang/test/Sema/unroll-template-value-crash.cpp index d8953c4845c26..cda4b897509b9 100644 --- a/clang/test/Sema/unroll-template-value-crash.cpp +++ b/clang/test/Sema/unroll-template-value-crash.cpp @@ -8,3 +8,28 @@ template <int Unroll> void foo() { #pragma GCC unroll Unroll for (int i = 0; i < Unroll; ++i); } + +struct val { + constexpr operator int() const { return 1; } +}; + +// generic lambda (using double template instantiation) + +template<typename T> +void use(T t) { + auto lam = [](auto N) { + #pragma clang loop unroll_count(N+1) + for (int i = 0; i < 10; ++i); + + #pragma unroll N+1 + for (int i = 0; i < 10; ++i); + + #pragma GCC unroll N+1 + for (int i = 0; i < 10; ++i); + }; + lam(t); +} + +void test() { + use(val()); +} `````````` </details> https://github.com/llvm/llvm-project/pull/172289 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
