r277797 - Fix crash in template type diffing.

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 4 20:16:36 PDT 2016


Author: rtrieu
Date: Thu Aug  4 22:16:36 2016
New Revision: 277797

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

When the type being diffed is a type alias, and the orginal type is not a
templated type, then there will be no unsugared TemplateSpecializationType.
When this happens, exit early from the constructor.  Also add assertions to
the other iterator accessor to prevent the iterator from being used.

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=277797&r1=277796&r2=277797&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Thu Aug  4 22:16:36 2016
@@ -916,6 +916,8 @@ class TemplateDiff {
       /// template argument.
       InternalIterator(const TemplateSpecializationType *TST)
           : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {
+        if (!TST) return;
+
         if (isEnd()) return;
 
         // Set to first template argument.  If not a parameter pack, done.
@@ -936,11 +938,13 @@ class TemplateDiff {
 
       /// isEnd - Returns true if the iterator is one past the end.
       bool isEnd() const {
+        assert(TST && "InternalalIterator is invalid with a null TST.");
         return Index >= TST->getNumArgs();
       }
 
       /// &operator++ - Increment the iterator to the next template argument.
       InternalIterator &operator++() {
+        assert(TST && "InternalalIterator is invalid with a null TST.");
         if (isEnd()) {
           return *this;
         }
@@ -976,6 +980,7 @@ class TemplateDiff {
 
       /// operator* - Returns the appropriate TemplateArgument.
       reference operator*() const {
+        assert(TST && "InternalalIterator is invalid with a null TST.");
         assert(!isEnd() && "Index exceeds number of arguments.");
         if (CurrentTA == EndTA)
           return TST->getArg(Index);
@@ -985,6 +990,7 @@ class TemplateDiff {
 
       /// operator-> - Allow access to the underlying TemplateArgument.
       pointer operator->() const {
+        assert(TST && "InternalalIterator is invalid with a null TST.");
         return &operator*();
       }
     };

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=277797&r1=277796&r2=277797&view=diff
==============================================================================
--- cfe/trunk/test/Misc/diag-template-diffing.cpp (original)
+++ cfe/trunk/test/Misc/diag-template-diffing.cpp Thu Aug  4 22:16:36 2016
@@ -1455,7 +1455,37 @@ void run() {
 }
 // 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
+}
+
+namespace TypeAlias2 {
+template <typename T>
+class A {};
+
+template <typename T>
+using A_reg = A<T>;
+void take_reg(A_reg<int>);
+
+template <typename T>
+using A_ptr = A<T> *;
+void take_ptr(A_ptr<int>);
 
+template <typename T>
+using A_ref = const A<T> &;
+void take_ref(A_ref<int>);
+
+void run(A_reg<float> reg, A_ptr<float> ptr, A_ref<float> ref) {
+  take_reg(reg);
+// CHECK-ELIDE-NOTREE: error: no matching function for call to 'take_reg'
+// CHECK-ELIDE-NOTREE: note:     candidate function not viable: no known conversion from 'A_reg<float>' to 'A_reg<int>' for 1st argument
+
+  take_ptr(ptr);
+// CHECK-ELIDE-NOTREE: error: no matching function for call to 'take_ptr'
+// CHECK-ELIDE-NOTREE: note:     candidate function not viable: no known conversion from 'A_ptr<float>' to 'A_ptr<int>' for 1st argument
+
+  take_ref(ref);
+// CHECK-ELIDE-NOTREE: error: no matching function for call to 'take_ref'
+// CHECK-ELIDE-NOTREE: note: candidate function not viable: no known conversion from 'const A<float>' to 'const A<int>' for 1st argument
+}
 }
 
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.




More information about the cfe-commits mailing list