
Fixed an assertion failure in debug mode, and potential crashes in release mode, when diagnosing a failed cast caused indirectly by a failed implicit conversion to the type of the constructor parameter. For instance ``` template<typename> struct StringTrait {}; template< int N > struct StringTrait< const char[ N ] > { typedef char CharType; static const MissingIntT length = N - 1; }; class String { public: template <typename T> String(T& str, typename StringTrait<T>::CharType = 0); }; class Exception { public: Exception(String const&); }; void foo() { throw Exception("some error"); } ``` `Exception(String const&)` is a matching constructor for `Exception` from a `const char*`, via an implicit conversion to `String`. However, the instantiation of the `String` constructor will fail because of the missing type `MissingIntT` inside the specialization of `StringTrait`. When trying to emit a diagnosis, `tryDiagnoseOverloadedCast` expects not to have a matching constructor, but there is; it just could not be instantiated.
27 lines
613 B
C++
27 lines
613 B
C++
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s
|
|
|
|
template<typename>
|
|
struct StringTrait {};
|
|
|
|
template< int N >
|
|
struct StringTrait< const char[ N ] > {
|
|
typedef char CharType;
|
|
static const MissingIntT length = N - 1; // expected-error {{unknown type name 'MissingIntT'}}
|
|
};
|
|
|
|
class String {
|
|
public:
|
|
template <typename T>
|
|
String(T& str, typename StringTrait<T>::CharType = 0);
|
|
};
|
|
|
|
|
|
class Exception {
|
|
public:
|
|
Exception(String const&);
|
|
};
|
|
|
|
void foo() {
|
|
throw Exception("some error"); // expected-error {{functional-style cast from 'const char[11]' to 'Exception' is not allowed}}
|
|
}
|