Skip to content

Commit

Permalink
[clang] Fix a crash when casting to an array type
Browse files Browse the repository at this point in the history
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
  • Loading branch information
alanzhao1 committed Jul 18, 2023
1 parent b0093e1 commit fe0116a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 1 deletion.
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,8 @@ Bug Fixes in This Version
that construct (`#62133 <https://github.com/llvm/llvm-project/issues/38717>_`).
- Fix crash caused by PseudoObjectExprBitfields: NumSubExprs overflow.
(`#63169 <https://github.com/llvm/llvm-project/issues/63169>_`)
- Fix crash when casting an object to an array type.
(`#63758 <https://github.com/llvm/llvm-project/issues/63758>_`)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
20 changes: 19 additions & 1 deletion clang/lib/Sema/SemaCast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
5 changes: 5 additions & 0 deletions clang/test/SemaCXX/paren-list-agg-init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
};

0 comments on commit fe0116a

Please sign in to comment.