Don't build expressions for invalid casts.

This matches how we normally perform semantic analysis for other sorts
of invalid expressions: it means we don't have to reason about invalid
sub-expressions.

Fixes PR16680.

llvm-svn: 187276
This commit is contained in:
Eli Friedman 2013-07-26 23:47:47 +00:00
parent 1836e60023
commit 3fd26b8514
2 changed files with 29 additions and 10 deletions

View File

@ -554,6 +554,7 @@ void CastOperation::CheckDynamicCast() {
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
<< this->DestType << DestRange;
SrcExpr = ExprError();
return;
}
@ -563,11 +564,14 @@ void CastOperation::CheckDynamicCast() {
} else if (DestRecord) {
if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
diag::err_bad_dynamic_cast_incomplete,
DestRange))
DestRange)) {
SrcExpr = ExprError();
return;
}
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
<< DestPointee.getUnqualifiedType() << DestRange;
SrcExpr = ExprError();
return;
}
@ -583,6 +587,7 @@ void CastOperation::CheckDynamicCast() {
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
<< OrigSrcType << SrcExpr.get()->getSourceRange();
SrcExpr = ExprError();
return;
}
} else if (DestReference->isLValueReferenceType()) {
@ -599,11 +604,14 @@ void CastOperation::CheckDynamicCast() {
if (SrcRecord) {
if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
diag::err_bad_dynamic_cast_incomplete,
SrcExpr.get()))
SrcExpr.get())) {
SrcExpr = ExprError();
return;
}
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
<< SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
SrcExpr = ExprError();
return;
}
@ -617,6 +625,7 @@ void CastOperation::CheckDynamicCast() {
if (!DestPointee.isAtLeastAsQualifiedAs(SrcPointee)) {
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)
<< CT_Dynamic << OrigSrcType << this->DestType << OpRange;
SrcExpr = ExprError();
return;
}
@ -632,8 +641,10 @@ void CastOperation::CheckDynamicCast() {
if (DestRecord && Self.IsDerivedFrom(SrcPointee, DestPointee)) {
if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,
OpRange.getBegin(), OpRange,
&BasePath))
return;
&BasePath)) {
SrcExpr = ExprError();
return;
}
Kind = CK_DerivedToBase;
@ -651,6 +662,7 @@ void CastOperation::CheckDynamicCast() {
if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
<< SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
SrcExpr = ExprError();
}
Self.MarkVTableUsed(OpRange.getBegin(),
cast<CXXRecordDecl>(SrcRecord->getDecl()));
@ -674,9 +686,11 @@ void CastOperation::CheckConstCast() {
unsigned msg = diag::err_bad_cxx_cast_generic;
if (TryConstCast(Self, SrcExpr, DestType, /*CStyle*/false, msg) != TC_Success
&& msg != 0)
&& msg != 0) {
Self.Diag(OpRange.getBegin(), msg) << CT_Const
<< SrcExpr.get()->getType() << DestType << OpRange;
SrcExpr = ExprError();
}
}
/// Check that a reinterpret_cast\<DestType\>(SrcExpr) is not used as upcast
@ -804,6 +818,7 @@ void CastOperation::CheckReinterpretCast() {
diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(),
DestType, /*listInitialization=*/false);
}
SrcExpr = ExprError();
} else if (tcr == TC_Success) {
if (Self.getLangOpts().ObjCAutoRefCount)
checkObjCARCConversion(Sema::CCK_OtherCast);
@ -865,6 +880,7 @@ void CastOperation::CheckStaticCast() {
diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType,
/*listInitialization=*/false);
}
SrcExpr = ExprError();
} else if (tcr == TC_Success) {
if (Kind == CK_BitCast)
checkCastAlign();
@ -1981,9 +1997,6 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
}
SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
if (SrcExpr.isInvalid())
return;
return;
}

View File

@ -16,8 +16,7 @@ struct B { // expected-note 3 {{candidate constructor (the implicit copy constru
int main () {
B(10); // expected-error {{no matching conversion for functional-style cast from 'int' to 'B'}}
(B)10; // expected-error {{no matching conversion for C-style cast from 'int' to 'B'}}
static_cast<B>(10); // expected-error {{no matching conversion for static_cast from 'int' to 'B'}} \\
// expected-warning {{expression result unused}}
static_cast<B>(10); // expected-error {{no matching conversion for static_cast from 'int' to 'B'}}
}
template<class T>
@ -73,3 +72,10 @@ struct AmbiguousCast {
long long AmbiguousCastFunc(AmbiguousCast& a) {
return static_cast<long long>(a); // expected-error {{ambiguous conversion for static_cast from 'AmbiguousCast' to 'long long'}}
}
namespace PR16680 {
void f(int (*__pf)());
int g() {
f(reinterpret_cast<int>(0.0f)); // expected-error {{reinterpret_cast from 'float' to 'int' is not allowed}}
}
}