]> granicus.if.org Git - clang/commitdiff
Fix some edge cases with C++ casts and placeholder expressions.
authorEli Friedman <eli.friedman@gmail.com>
Thu, 12 Jan 2012 00:44:34 +0000 (00:44 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Thu, 12 Jan 2012 00:44:34 +0000 (00:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147984 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaCast.cpp
test/SemaObjCXX/properties.mm

index 0250b3e3800cabdf81c107b26455a0aaef6543ad..2c7611de6b5f513eff14863861631f3c05ef2bcb 100644 (file)
@@ -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 = 
index d56ac157576f54c50936b6ba31393953a8a3a95a..62fddc9b7cdaf883801fc2d4c11b790726aa611a 100644 (file)
@@ -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);
+}