r204005 - Fix PR18806: Canonicalize the replacement type when deserializing a SubstTemplateTypeParmType

Stephan Tolksdorf st at quanttec.com
Sat Mar 15 03:23:27 PDT 2014


Author: stephant
Date: Sat Mar 15 05:23:27 2014
New Revision: 204005

URL: http://llvm.org/viewvc/llvm-project?rev=204005&view=rev
Log:
Fix PR18806: Canonicalize the replacement type when deserializing a SubstTemplateTypeParmType

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

Added:
    cfe/trunk/test/PCH/pr18806.cpp
Modified:
    cfe/trunk/lib/Serialization/ASTReader.cpp

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=204005&r1=204004&r2=204005&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sat Mar 15 05:23:27 2014
@@ -5203,9 +5203,9 @@ QualType ASTReader::readTypeRecord(unsig
     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: {

Added: cfe/trunk/test/PCH/pr18806.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pr18806.cpp?rev=204005&view=auto
==============================================================================
--- cfe/trunk/test/PCH/pr18806.cpp (added)
+++ cfe/trunk/test/PCH/pr18806.cpp Sat Mar 15 05:23:27 2014
@@ -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





More information about the cfe-commits mailing list