forked from OSchip/llvm-project
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. llvm-svn: 264940
This commit is contained in:
parent
85daf65c5a
commit
a7564d7d66
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue