From ed0b31f8474b60661de6cbb75fb04aa0de9bd1ef Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Thu, 12 Jan 2012 00:44:34 +0000 Subject: [PATCH] Fix some edge cases with C++ casts and placeholder expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147984 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaCast.cpp | 27 +++++++++++++++------------ test/SemaObjCXX/properties.mm | 9 +++++++++ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index 0250b3e380..2c7611de6b 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -529,11 +529,12 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, /// Refer to C++ 5.2.7 for details. Dynamic casts are used mostly for runtime- /// checked downcasts in class hierarchies. void CastOperation::CheckDynamicCast() { - if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload)) { + if (ValueKind == VK_RValue) SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); - if (SrcExpr.isInvalid()) // if conversion failed, don't report another error - return; - } + else if (isPlaceholder()) + SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take()); + if (SrcExpr.isInvalid()) // if conversion failed, don't report another error + return; QualType OrigSrcType = SrcExpr.get()->getType(); QualType DestType = Self.Context.getCanonicalType(this->DestType); @@ -662,11 +663,12 @@ void CastOperation::CheckDynamicCast() { /// const char *str = "literal"; /// legacy_function(const_cast\(str)); void CastOperation::CheckConstCast() { - if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload)) { + if (ValueKind == VK_RValue) SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); - if (SrcExpr.isInvalid()) // if conversion failed, don't report another error - return; - } + else if (isPlaceholder()) + SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take()); + if (SrcExpr.isInvalid()) // if conversion failed, don't report another error + return; unsigned msg = diag::err_bad_cxx_cast_generic; if (TryConstCast(Self, SrcExpr.get(), DestType, /*CStyle*/false, msg) != TC_Success @@ -681,11 +683,12 @@ void CastOperation::CheckConstCast() { /// like this: /// char *bytes = reinterpret_cast\(int_ptr); void CastOperation::CheckReinterpretCast() { - if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload)) { + if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload)) SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); - if (SrcExpr.isInvalid()) // if conversion failed, don't report another error - return; - } + else + checkNonOverloadPlaceholders(); + if (SrcExpr.isInvalid()) // if conversion failed, don't report another error + return; unsigned msg = diag::err_bad_cxx_cast_generic; TryCastResult tcr = diff --git a/test/SemaObjCXX/properties.mm b/test/SemaObjCXX/properties.mm index d56ac15757..62fddc9b7c 100644 --- a/test/SemaObjCXX/properties.mm +++ b/test/SemaObjCXX/properties.mm @@ -40,3 +40,12 @@ void test3(Test3 *t) { char vla[t.length] = {}; // expected-error {{variable-sized object may not be initialized}} char *heaparray = new char[t.length]; } + +@interface Test4 +- (X&) prop; +@end +void test4(Test4 *t) { + (void)const_cast(t.prop); + (void)dynamic_cast(t.prop); + (void)reinterpret_cast(t.prop); +} -- 2.50.1