From fe0116aba833ee8597e2155d1e555c326acfaafc Mon Sep 17 00:00:00 2001 From: Alan Zhao Date: Mon, 17 Jul 2023 15:27:32 -0700 Subject: [PATCH] [clang] Fix a crash when casting to an array type In C++20, if Clang fails to perform constructor overload on a RecordType, then Clang will try to perform parentesized aggregate initialization. If that fails and the initialization was attempted as part of a cast, then we should get the diagnostics from the failed constructor overload attempt. However, we don't attempt constructor overloading for arrays, so previously, if we try to diagnose an overloaded cast for a parenthesized aggregate initialization of an array, we crash. To fix this, we now exit tryDiagnoseOverloadedCast(...) for failed parentesized list initialization if the destination type is an array. Fixes #63758 Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D155523 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaCast.cpp | 20 +++++++++++++++++++- clang/test/SemaCXX/paren-list-agg-init.cpp | 5 +++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index acc92b2..dd316a7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -634,6 +634,8 @@ Bug Fixes in This Version that construct (`#62133 _`). - Fix crash caused by PseudoObjectExprBitfields: NumSubExprs overflow. (`#63169 _`) +- Fix crash when casting an object to an array type. + (`#63758 _`) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index fc48f63..d65ecf5 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -454,9 +454,27 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, switch (sequence.getFailureKind()) { default: return false; + case InitializationSequence::FK_ParenthesizedListInitFailed: + // In C++20, if the underlying destination type is a RecordType, Clang + // attempts to perform parentesized aggregate initialization if constructor + // overload fails: + // + // C++20 [expr.static.cast]p4: + // An expression E can be explicitly converted to a type T...if overload + // resolution for a direct-initialization...would find at least one viable + // function ([over.match.viable]), or if T is an aggregate type having a + // first element X and there is an implicit conversion sequence from E to + // the type of X. + // + // If that fails, then we'll generate the diagnostics from the failed + // previous constructor overload attempt. Array initialization, however, is + // not done after attempting constructor overloading, so we exit as there + // won't be a failed overload result. + if (destType->isArrayType()) + return false; + break; case InitializationSequence::FK_ConstructorOverloadFailed: case InitializationSequence::FK_UserConversionOverloadFailed: - case InitializationSequence::FK_ParenthesizedListInitFailed: break; } diff --git a/clang/test/SemaCXX/paren-list-agg-init.cpp b/clang/test/SemaCXX/paren-list-agg-init.cpp index 88d9b95..e2eec177 100644 --- a/clang/test/SemaCXX/paren-list-agg-init.cpp +++ b/clang/test/SemaCXX/paren-list-agg-init.cpp @@ -294,3 +294,8 @@ int test() { } } + +namespace gh63758 { + struct S {} s; + auto words = (char[])s; // expected-error {{C-style cast from 'struct S' to 'char[]' is not allowed}} +}; -- 2.7.4