Thanks for the review! And yes, I was referring to 18806. Sorry for the typo.

  I've added a test case that triggers the assert violation without this patch.

  What's going on in the test case is this:

  When the header is parsed, decltype(B()) is canonicalized to decltype(Y()), 
because that was the first parsed equivalent decltype expression. Hence, the 
TemplateSpecializationType for Id<decltype(B())> ends up with 
SubstTemplateTypeParmType(T, decltype(Y())) as the AliasedType member.

  When the cpp file is compiled and the AST reader reads Id<decltype(B())>, it 
sees decltype(B()) before decltype(Y()). So, this time decltype(B()) ends up 
being the canonical type for both decltypes, which leads to an assert violation 
when the reader calls getSubstTemplateTypeParmType with the non-canonical 
decltype(Y()) as the replacement type.

Hi rsmith,

http://llvm-reviews.chandlerc.com/D3073

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D3073?vs=7817&id=7847#toc

Files:
  lib/Serialization/ASTReader.cpp
  test/PCH/pr18806.cpp

Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -5189,9 +5189,9 @@
     unsigned Idx = 0;
     QualType Parm = readType(*Loc.F, Record, Idx);
     QualType Replacement = readType(*Loc.F, Record, Idx);
-    return
-      Context.getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
-                                            Replacement);
+    return Context.getSubstTemplateTypeParmType(
+        cast<TemplateTypeParmType>(Parm),
+        Context.getCanonicalType(Replacement));
   }
 
   case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: {
Index: test/PCH/pr18806.cpp
===================================================================
--- /dev/null
+++ test/PCH/pr18806.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s
+
+// expected-no-diagnostics
+
+// Before the patch, this test triggered an assert violation in
+// ASTContext::getSubstTemplateTypeParmType.
+
+#ifndef HEADER_INCLUDED
+#define HEADER_INCLUDED
+
+template <typename T>
+using Id = T;
+
+template <typename X>
+struct Class1 {
+  template <typename Y, typename = decltype(Y())>
+  struct Nested1;
+};
+
+template <typename A>
+struct Class2 {
+  template <typename B, typename = Id<decltype(B())>>
+  struct Nested2;
+};
+
+#else
+
+Class2<char> test;
+
+#endif
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -5189,9 +5189,9 @@
     unsigned Idx = 0;
     QualType Parm = readType(*Loc.F, Record, Idx);
     QualType Replacement = readType(*Loc.F, Record, Idx);
-    return
-      Context.getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
-                                            Replacement);
+    return Context.getSubstTemplateTypeParmType(
+        cast<TemplateTypeParmType>(Parm),
+        Context.getCanonicalType(Replacement));
   }
 
   case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: {
Index: test/PCH/pr18806.cpp
===================================================================
--- /dev/null
+++ test/PCH/pr18806.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s
+
+// expected-no-diagnostics
+
+// Before the patch, this test triggered an assert violation in
+// ASTContext::getSubstTemplateTypeParmType.
+
+#ifndef HEADER_INCLUDED
+#define HEADER_INCLUDED
+
+template <typename T>
+using Id = T;
+
+template <typename X>
+struct Class1 {
+  template <typename Y, typename = decltype(Y())>
+  struct Nested1;
+};
+
+template <typename A>
+struct Class2 {
+  template <typename B, typename = Id<decltype(B())>>
+  struct Nested2;
+};
+
+#else
+
+Class2<char> test;
+
+#endif
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to