]> granicus.if.org Git - clang/commitdiff
Fix PR18806: Canonicalize the replacement type when deserializing a SubstTemplateType...
authorStephan Tolksdorf <st@quanttec.com>
Sat, 15 Mar 2014 10:23:27 +0000 (10:23 +0000)
committerStephan Tolksdorf <st@quanttec.com>
Sat, 15 Mar 2014 10:23:27 +0000 (10:23 +0000)
What's going on in the test case (without the patch applied) 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 PCH file is included 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.

Reviewers: rsmith

Reviewed By: rsmith

CC: cfe-commits, aemerson
Differential Revision: http://llvm-reviews.chandlerc.com/D3073

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204005 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Serialization/ASTReader.cpp
test/PCH/pr18806.cpp [new file with mode: 0644]

index 7781a7d1b05e1c3a1267883d0796315ecfd7e18c..a0ee3d37c5cef7b989f8fe450f2b56e6e8b435af 100644 (file)
@@ -5203,9 +5203,9 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
     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: {
diff --git a/test/PCH/pr18806.cpp b/test/PCH/pr18806.cpp
new file mode 100644 (file)
index 0000000..c28320d
--- /dev/null
@@ -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