From 051e237a7fd6b0ed4e5b9d1a1e16ef8a3cd5bb14 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Thu, 19 Dec 2013 02:05:20 +0000 Subject: [PATCH] PCH: fix a crash caused by a circular deserialization dependency We started by trying to deserialize decltype(func-param) in a trailing return type, which causes the function parameter decl to be deserialized, which pulls in the function decl, which pulls the function type, which pulls the same decltype() in the return type, and then we crashed. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197644 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Serialization/ASTReaderDecl.cpp | 11 ++++--- test/PCH/cxx-templates.h | 47 +++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 70fb062b2c..c2e286814b 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -356,11 +356,14 @@ void ASTDeclReader::Visit(Decl *D) { } void ASTDeclReader::VisitDecl(Decl *D) { - if (D->isTemplateParameter()) { + if (D->isTemplateParameter() || D->isTemplateParameterPack() || + isa(D)) { // We don't want to deserialize the DeclContext of a template - // parameter immediately, because the template parameter might be - // used in the formulation of its DeclContext. Use the translation - // unit DeclContext as a placeholder. + // parameter or of a parameter of a function template immediately. These + // entities might be used in the formulation of its DeclContext (for + // example, a function parameter can be used in decltype() in trailing + // return type of the function). Use the translation unit DeclContext as a + // placeholder. GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID(Record, Idx); GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID(Record, Idx); Reader.addPendingDeclContextInfo(D, diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h index 992f478e33..c4a8447276 100644 --- a/test/PCH/cxx-templates.h +++ b/test/PCH/cxx-templates.h @@ -311,3 +311,50 @@ namespace local_extern { return sizeof(arr); } } + +namespace rdar15468709a { + template struct decay {}; + + template auto foo(FooParamTy fooParam) -> decltype(fooParam); + template auto bar(BarParamTy barParam) -> decay; + + struct B {}; + + void crash() { + B some; + bar(some); + } +} + +namespace rdar15468709b { + template struct decay {}; + + template int returnsInt(Foos... foos); + + template auto foo(FooParamTy... fooParam) -> decltype(returnsInt(fooParam...)); + template auto bar(BarParamTy... barParam) -> decay; + + struct B {}; + + void crash() { + B some; + bar(some); + } +} + +namespace rdar15468709c { + template struct decay {}; + + template int returnsInt(Foos... foos); + + template void foo(FooParamTy fooParam) { decltype(fooParam) a; } + template auto bar(BarParamTy barParam) -> decay; + + struct B {}; + + void crash() { + B some; + bar(some); + } +} + -- 2.50.0