r264940 - Fix Clang crash with template type diffing.

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 30 15:23:02 PDT 2016


Author: rtrieu
Date: Wed Mar 30 17:23:00 2016
New Revision: 264940

URL: http://llvm.org/viewvc/llvm-project?rev=264940&view=rev
Log:
Fix Clang crash with template type diffing.

Fixes https://llvm.org/bugs/show_bug.cgi?id=27129 which is crash involving type
aliases and template type diffing.  Template arguments for type aliases and
template arguments for the underlying desugared type may not have one-to-one
relations, which could mess us the attempt to get more information from the
desugared type.  For type aliases, ignore the iterator over the desugared type.

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=264940&r1=264939&r2=264940&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Wed Mar 30 17:23:00 2016
@@ -990,19 +990,22 @@ class TemplateDiff {
       }
     };
 
+    bool UseDesugaredIterator;
     InternalIterator SugaredIterator;
     InternalIterator DesugaredIterator;
 
   public:
     TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)
-        : SugaredIterator(TST),
+        : UseDesugaredIterator(TST->isSugared() && !TST->isTypeAlias()),
+          SugaredIterator(TST),
           DesugaredIterator(
               GetTemplateSpecializationType(Context, TST->desugar())) {}
 
     /// &operator++ - Increment the iterator to the next template argument.
     TSTiterator &operator++() {
       ++SugaredIterator;
-      ++DesugaredIterator;
+      if (UseDesugaredIterator)
+        ++DesugaredIterator;
       return *this;
     }
 
@@ -1024,11 +1027,13 @@ class TemplateDiff {
     /// hasDesugaredTA - Returns true if there is another TemplateArgument
     /// available.
     bool hasDesugaredTA() const {
-      return !DesugaredIterator.isEnd();
+      return UseDesugaredIterator && !DesugaredIterator.isEnd();
     }
 
     /// getDesugaredTA - Returns the desugared TemplateArgument.
     reference getDesugaredTA() const {
+      assert(UseDesugaredIterator &&
+             "Desugared TemplateArgument should not be used.");
       return *DesugaredIterator;
     }
   };

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=264940&r1=264939&r2=264940&view=diff
==============================================================================
--- cfe/trunk/test/Misc/diag-template-diffing.cpp (original)
+++ cfe/trunk/test/Misc/diag-template-diffing.cpp Wed Mar 30 17:23:00 2016
@@ -1421,6 +1421,43 @@ B<const A<>> b4 = B<>();
 // CHECK-ELIDE-NOTREE: error: no viable conversion from 'B<A<...>>' to 'B<const A<...>>'
 }
 
+namespace TypeAlias {
+
+template <typename T> class vector {};
+
+template <int Dimension> class Point;
+template <int dimension, typename T> using Polygon = vector<Point<dimension>>;
+
+void foo(Polygon<3, float>);
+void bar() { foo(Polygon<2, float>()); }
+
+// CHECK-ELIDE-NOTREE: error: no matching function for call to 'foo'
+// CHECK-ELIDE-NOTREE: note: candidate function not viable: no known conversion from 'Polygon<2, [...]>' to 'Polygon<3, [...]>' for 1st argument
+
+enum class X {
+  X1,
+  X2,
+};
+
+template<X x> struct EnumToType;
+
+template <> struct EnumToType<X::X1> { using type = int; };
+
+template <> struct EnumToType<X::X2> { using type = double; };
+
+
+template <X x> using VectorType = vector<typename EnumToType<x>::type>;
+
+template <X x> void D(const VectorType<x>&);
+
+void run() {
+  D<X::X1>(VectorType<X::X2>());
+}
+// CHECK-ELIDE-NOTREE: error: no matching function for call to 'D'
+// CHECK-ELIDE-NOTREE: note: candidate function [with x = TypeAlias::X::X1] not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(TypeAlias::X)0>' for 1st argument
+
+}
+
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.




More information about the cfe-commits mailing list