Author: Alejandro Álvarez Ayllón Date: 2024-09-18T10:11:03+02:00 New Revision: 0dd56858fe188419182a57d0e03c8cd0aa693867
URL: https://github.com/llvm/llvm-project/commit/0dd56858fe188419182a57d0e03c8cd0aa693867 DIFF: https://github.com/llvm/llvm-project/commit/0dd56858fe188419182a57d0e03c8cd0aa693867.diff LOG: [clang][Sema] Fix assertion in `tryDiagnoseOverloadedCast` (#108021) 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. Added: clang/test/Parser/cxx-bad-cast-diagnose-broken-template.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaCast.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index af3ab14d70d871..3ed9a2984a38fe 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -397,6 +397,8 @@ Bug Fixes to C++ Support - Fixed a crash when clang tries to subtitute parameter pack while retaining the parameter pack. #GH63819, #GH107560 - Fix a crash when a static assert declaration has an invalid close location. (#GH108687) +- 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. Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index f01b22a72915c8..6ac6201843476b 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -446,7 +446,12 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, : InitializationKind::CreateCast(/*type range?*/ range); InitializationSequence sequence(S, entity, initKind, src); - assert(sequence.Failed() && "initialization succeeded on second try?"); + // It could happen that a constructor failed to be used because + // it requires a temporary of a broken type. Still, it will be found when + // looking for a match. + if (!sequence.Failed()) + return false; + switch (sequence.getFailureKind()) { default: return false; diff --git a/clang/test/Parser/cxx-bad-cast-diagnose-broken-template.cpp b/clang/test/Parser/cxx-bad-cast-diagnose-broken-template.cpp new file mode 100644 index 00000000000000..3500975d936953 --- /dev/null +++ b/clang/test/Parser/cxx-bad-cast-diagnose-broken-template.cpp @@ -0,0 +1,26 @@ +// 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}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits