diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-01-12 00:44:34 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-01-12 00:44:34 +0000 |
commit | 42b199c699d327dcfe94e05d476051a0db91c3dc (patch) | |
tree | bccb2f950eccf8b54b743459287f90f6cde69177 | |
parent | 5886fb5bd361bafa04aeb5ff8a278948de8e14f5 (diff) | |
download | bcm5719-llvm-42b199c699d327dcfe94e05d476051a0db91c3dc.tar.gz bcm5719-llvm-42b199c699d327dcfe94e05d476051a0db91c3dc.zip |
Fix some edge cases with C++ casts and placeholder expressions.
llvm-svn: 147984
-rw-r--r-- | clang/lib/Sema/SemaCast.cpp | 27 | ||||
-rw-r--r-- | clang/test/SemaObjCXX/properties.mm | 9 |
2 files changed, 24 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 0250b3e3800..2c7611de6b5 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/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/clang/test/SemaObjCXX/properties.mm b/clang/test/SemaObjCXX/properties.mm index d56ac157576..62fddc9b7cd 100644 --- a/clang/test/SemaObjCXX/properties.mm +++ b/clang/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); +} |