From: Eli Friedman Date: Fri, 26 Jul 2013 23:47:47 +0000 (+0000) Subject: Don't build expressions for invalid casts. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2437c8642da2728aab47262ffb74dfa796a1cf35;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187276 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index 9bf8d0a5ab..1adb037f0e 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -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(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(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\(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; } diff --git a/test/SemaCXX/cast-conversion.cpp b/test/SemaCXX/cast-conversion.cpp index 76b09997ef..4d5abfdcfb 100644 --- a/test/SemaCXX/cast-conversion.cpp +++ b/test/SemaCXX/cast-conversion.cpp @@ -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(10); // expected-error {{no matching conversion for static_cast from 'int' to 'B'}} \\ - // expected-warning {{expression result unused}} + static_cast(10); // expected-error {{no matching conversion for static_cast from 'int' to 'B'}} } template @@ -73,3 +72,10 @@ struct AmbiguousCast { long long AmbiguousCastFunc(AmbiguousCast& a) { return static_cast(a); // expected-error {{ambiguous conversion for static_cast from 'AmbiguousCast' to 'long long'}} } + +namespace PR16680 { + void f(int (*__pf)()); + int g() { + f(reinterpret_cast(0.0f)); // expected-error {{reinterpret_cast from 'float' to 'int' is not allowed}} + } +}