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
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index 0250b3e..2c7611d 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -529,11 +529,12 @@
 /// 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 @@
 /// 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 @@
 /// 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 d56ac15..62fddc9 100644
--- a/test/SemaObjCXX/properties.mm
+++ b/test/SemaObjCXX/properties.mm
@@ -40,3 +40,12 @@
   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);
+}