llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: eiytoq (eiytoq) <details> <summary>Changes</summary> ## Summary This patch fixes an assertion crash during template instantiation in `TreeTransform<Derived>::TransformCXXTypeidExpr`. When transforming `typeid(expr)`, Clang may query `isPolymorphic()` on a `CXXRecordDecl` that is incomplete, which can trigger `CXXRecordDecl::data()` assertions. ## Root cause In `TransformCXXTypeidExpr`, the glvalue path used: - `RD && RD->isPolymorphic()` For local/injected incomplete class types, `RD` exists but has no definition, so querying polymorphic-ness is invalid in this context. ## Fix Require a complete definition before checking polymorphic-ness: - `RD && RD->hasDefinition() && RD->isPolymorphic()` This preserves existing behavior for complete types while avoiding assertion failures for incomplete ones. Fixes #<!-- -->63242 Fixes #<!-- -->176397 --- Full diff: https://github.com/llvm/llvm-project/pull/180442.diff 2 Files Affected: - (modified) clang/lib/Sema/TreeTransform.h (+1-1) - (added) clang/test/SemaCXX/typeid-incomplete-local-crash.cpp (+39) ``````````diff diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index fb32b0e70e3c9..3b7f5d8d66507 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -14521,7 +14521,7 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) { auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated; if (E->isGLValue()) if (auto *RD = Op->getType()->getAsCXXRecordDecl(); - RD && RD->isPolymorphic()) + RD && RD->hasDefinition() && RD->isPolymorphic()) EvalCtx = SemaRef.ExprEvalContexts.back().Context; EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx, diff --git a/clang/test/SemaCXX/typeid-incomplete-local-crash.cpp b/clang/test/SemaCXX/typeid-incomplete-local-crash.cpp new file mode 100644 index 0000000000000..5d7922257b15c --- /dev/null +++ b/clang/test/SemaCXX/typeid-incomplete-local-crash.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s + +namespace std { +class type_info; +} + +namespace gh176397 { +auto recursiveLambda = [](auto, int) { + struct S; // expected-note {{member is declared here}} + typeid(*static_cast<S *>(nullptr)); // expected-error {{implicit instantiation of undefined member 'S'}} +}; + +void test() { + recursiveLambda(recursiveLambda, 10); // expected-note {{in instantiation of function template specialization}} +} +} // namespace gh176397 + +namespace gh63242 { +struct scoped { + enum class scoped2 { + RED, + YELLOW, + GREEN + }; +}; + +template <auto N> +struct scoped_struct { + void f() { + class scoped2 e = scoped::scoped2::RED; // expected-error {{implicit instantiation of undefined member 'scoped2'}} expected-note {{member is declared here}} + (void)typeid(e); + } +}; + +void test() { + scoped_struct<scoped::scoped2::RED> s; + s.f(); // expected-note {{in instantiation of member function 'gh63242::scoped_struct<gh63242::scoped::scoped2::RED>::f' requested here}} +} +} // namespace gh63242 `````````` </details> https://github.com/llvm/llvm-project/pull/180442 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
