r192202 - Fix an edge case in the template differ with default arguments.

Benjamin Kramer benny.kra at googlemail.com
Tue Oct 8 09:58:52 PDT 2013


Author: d0k
Date: Tue Oct  8 11:58:52 2013
New Revision: 192202

URL: http://llvm.org/viewvc/llvm-project?rev=192202&view=rev
Log:
Fix an edge case in the template differ with default arguments.

In the test case one type is coming from a typedef with no default arg, the
other has the default arg. Taking the default arg from the typedef crashes, so
always use the real template paramter declaration. PR17510.

Modified:
    cfe/trunk/lib/AST/ASTDiagnostic.cpp
    cfe/trunk/test/Misc/diag-template-diffing.cpp

Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=192202&r1=192201&r2=192202&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Tue Oct  8 11:58:52 2013
@@ -831,8 +831,10 @@ class TemplateDiff {
   void DiffTemplate(const TemplateSpecializationType *FromTST,
                     const TemplateSpecializationType *ToTST) {
     // Begin descent into diffing template tree.
-    TemplateParameterList *Params =
+    TemplateParameterList *ParamsFrom =
         FromTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters();
+    TemplateParameterList *ParamsTo =
+        ToTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters();
     unsigned TotalArgs = 0;
     for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST);
          !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) {
@@ -841,15 +843,18 @@ class TemplateDiff {
       // Get the parameter at index TotalArgs.  If index is larger
       // than the total number of parameters, then there is an
       // argument pack, so re-use the last parameter.
-      NamedDecl *ParamND = Params->getParam(
-          (TotalArgs < Params->size()) ? TotalArgs
-                                       : Params->size() - 1);
+      unsigned ParamIndex = std::min(TotalArgs, ParamsFrom->size() - 1);
+      NamedDecl *ParamND = ParamsFrom->getParam(ParamIndex);
+
       // Handle Types
       if (TemplateTypeParmDecl *DefaultTTPD =
               dyn_cast<TemplateTypeParmDecl>(ParamND)) {
         QualType FromType, ToType;
         FromType = GetType(FromIter, DefaultTTPD);
-        ToType = GetType(ToIter, DefaultTTPD);
+        // A forward declaration can have no default arg but the actual class
+        // can, don't mix up iterators and get the original parameter.
+        ToType = GetType(
+            ToIter, cast<TemplateTypeParmDecl>(ParamsTo->getParam(ParamIndex)));
         Tree.SetNode(FromType, ToType);
         Tree.SetDefault(FromIter.isEnd() && !FromType.isNull(),
                         ToIter.isEnd() && !ToType.isNull());

Modified: cfe/trunk/test/Misc/diag-template-diffing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing.cpp?rev=192202&r1=192201&r2=192202&view=diff
==============================================================================
--- cfe/trunk/test/Misc/diag-template-diffing.cpp (original)
+++ cfe/trunk/test/Misc/diag-template-diffing.cpp Tue Oct  8 11:58:52 2013
@@ -1051,8 +1051,24 @@ namespace DependentInt {
   }
 }
 
+namespace PR17510 {
+class Atom;
+
+template <typename T> class allocator;
+template <typename T, typename A> class vector;
+
+typedef vector<const Atom *, allocator<const Atom *> > AtomVector;
+
+template <typename T, typename A = allocator<const Atom *> > class vector {};
+
+void foo() {
+  vector<Atom *> v;
+  AtomVector v2(v);
+  // CHECK-ELIDE-NOTREE: no known conversion from 'vector<class PR17510::Atom *, [...]>' to 'const vector<const class PR17510::Atom *, [...]>'
+}
+}
+
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-TREE: {{[0-9]*}} errors generated.
-





More information about the cfe-commits mailing list