diff options
-rw-r--r-- | lib/Sema/SemaCast.cpp | 27 | ||||
-rw-r--r-- | 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\<char*\>(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\<char*\>(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<const X&>(t.prop); + (void)dynamic_cast<X&>(t.prop); + (void)reinterpret_cast<int&>(t.prop); +} |