r197644 - PCH: fix a crash caused by a circular deserialization dependency

Dmitri Gribenko gribozavr at gmail.com
Wed Dec 18 18:05:20 PST 2013


Author: gribozavr
Date: Wed Dec 18 20:05:20 2013
New Revision: 197644

URL: http://llvm.org/viewvc/llvm-project?rev=197644&view=rev
Log:
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.

Modified:
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/test/PCH/cxx-templates.h

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=197644&r1=197643&r2=197644&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Dec 18 20:05:20 2013
@@ -356,11 +356,14 @@ void ASTDeclReader::Visit(Decl *D) {
 }
 
 void ASTDeclReader::VisitDecl(Decl *D) {
-  if (D->isTemplateParameter()) {
+  if (D->isTemplateParameter() || D->isTemplateParameterPack() ||
+      isa<ParmVarDecl>(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,

Modified: cfe/trunk/test/PCH/cxx-templates.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.h?rev=197644&r1=197643&r2=197644&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.h (original)
+++ cfe/trunk/test/PCH/cxx-templates.h Wed Dec 18 20:05:20 2013
@@ -311,3 +311,50 @@ namespace local_extern {
     return sizeof(arr);
   }
 }
+
+namespace rdar15468709a {
+  template<typename> struct decay {};
+
+  template<typename FooParamTy> auto foo(FooParamTy fooParam) -> decltype(fooParam);
+  template<typename BarParamTy> auto bar(BarParamTy barParam) -> decay<decltype(barParam)>;
+
+  struct B {};
+
+  void crash() {
+    B some;
+    bar(some);
+  }
+}
+
+namespace rdar15468709b {
+  template<typename> struct decay {};
+
+  template<typename... Foos> int returnsInt(Foos... foos);
+
+  template<typename... FooParamTy> auto foo(FooParamTy... fooParam) -> decltype(returnsInt(fooParam...));
+  template<typename... BarParamTy> auto bar(BarParamTy... barParam) -> decay<decltype(returnsInt(barParam...))>;
+
+  struct B {};
+
+  void crash() {
+    B some;
+    bar(some);
+  }
+}
+
+namespace rdar15468709c {
+  template<typename> struct decay {};
+
+  template<class... Foos> int returnsInt(Foos... foos);
+
+  template<typename FooParamTy> void foo(FooParamTy fooParam) { decltype(fooParam) a; }
+  template<typename BarParamTy> auto bar(BarParamTy barParam) -> decay<decltype(barParam)>;
+
+  struct B {};
+
+  void crash() {
+    B some;
+    bar(some);
+  }
+}
+





More information about the cfe-commits mailing list