mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 13:06:09 +00:00
Switch static_cast from the old reference-initialization code (via
CheckReferenceInit) over to the new initialization code (InitializationSequence), which is better-tested and doesn't require us to compute the entire conversion sequence twice. llvm-svn: 99452
This commit is contained in:
parent
1d38538fb6
commit
deb714ceeb
@ -913,27 +913,24 @@ TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
|
||||
// At this point of CheckStaticCast, if the destination is a reference,
|
||||
// this has to work. There is no other way that works.
|
||||
// On the other hand, if we're checking a C-style cast, we've still got
|
||||
// the reinterpret_cast way. So in C-style mode, we first try the call
|
||||
// with an ICS to suppress errors.
|
||||
if (CStyle) {
|
||||
ImplicitConversionSequence ICS;
|
||||
if(Self.CheckReferenceInit(SrcExpr, DestType, OpRange.getBegin(),
|
||||
/*SuppressUserConversions=*/false,
|
||||
/*AllowExplicit=*/false, /*ForceRValue=*/false,
|
||||
&ICS))
|
||||
return TC_NotApplicable;
|
||||
// the reinterpret_cast way.
|
||||
InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
|
||||
InitializationKind InitKind = InitializationKind::CreateCast(OpRange,
|
||||
CStyle);
|
||||
InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExpr, 1);
|
||||
if (InitSeq.getKind() == InitializationSequence::FailedSequence && CStyle)
|
||||
return TC_NotApplicable;
|
||||
|
||||
Sema::OwningExprResult Result
|
||||
= InitSeq.Perform(Self, Entity, InitKind,
|
||||
Action::MultiExprArg(Self, (void**)&SrcExpr, 1));
|
||||
if (Result.isInvalid()) {
|
||||
msg = 0;
|
||||
return TC_Failed;
|
||||
}
|
||||
// Now we're committed either way.
|
||||
if(!Self.CheckReferenceInit(SrcExpr, DestType, OpRange.getBegin(),
|
||||
/*SuppressUserConversions=*/false,
|
||||
/*AllowExplicit=*/false,
|
||||
/*ForceRValue=*/false, 0,
|
||||
/*IgnoreBaseAccess=*/CStyle))
|
||||
return TC_Success;
|
||||
|
||||
// We already got an error message.
|
||||
msg = 0;
|
||||
return TC_Failed;
|
||||
|
||||
SrcExpr = Result.takeAs<Expr>();
|
||||
return TC_Success;
|
||||
}
|
||||
|
||||
if (DestType->isRecordType()) {
|
||||
|
@ -60,7 +60,7 @@ void t_529_2()
|
||||
(void)static_cast<A*>((H*)0); // expected-error {{ambiguous conversion}}
|
||||
(void)static_cast<int>((int*)0); // expected-error {{static_cast from 'int *' to 'int' is not allowed}}
|
||||
(void)static_cast<A**>((B**)0); // expected-error {{static_cast from 'B **' to 'A **' is not allowed}}
|
||||
(void)static_cast<char&>(i); // expected-error {{non-const lvalue reference to type 'char' cannot be initialized with a value of type 'int'}}
|
||||
(void)static_cast<char&>(i); // expected-error {{non-const lvalue reference to type 'char' cannot bind to a value of unrelated type 'int'}}
|
||||
}
|
||||
|
||||
// Anything to void
|
||||
@ -91,7 +91,7 @@ void t_529_5_8()
|
||||
(void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
|
||||
(void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
|
||||
(void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'B *' to 'E *' is not allowed}}
|
||||
(void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'E' cannot be initialized with a value of type 'B'}}
|
||||
(void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'E' cannot bind to a value of unrelated type 'B'}}
|
||||
|
||||
// TODO: Test inaccessible base in context where it's accessible, i.e.
|
||||
// member function and friend.
|
||||
|
Loading…
x
Reference in New Issue
Block a user