Allow downcasts of pointers to Objective-C interfaces, with a
warning. This matches GCC's behavior and addresses
<rdar://problem/6458293>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61246 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e951016..e18f143 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -708,14 +708,16 @@
/// PerformImplicitConversion - Perform an implicit conversion of the
/// expression From to the type ToType. Returns true if there was an
/// error, false otherwise. The expression From is replaced with the
-/// converted expression.
+/// converted expression. Flavor is the kind of conversion we're
+/// performing, used in the error message.
bool
-Sema::PerformImplicitConversion(Expr *&From, QualType ToType)
+Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
+ const char *Flavor)
{
ImplicitConversionSequence ICS = TryImplicitConversion(From, ToType);
switch (ICS.ConversionKind) {
case ImplicitConversionSequence::StandardConversion:
- if (PerformImplicitConversion(From, ToType, ICS.Standard))
+ if (PerformImplicitConversion(From, ToType, ICS.Standard, Flavor))
return true;
break;
@@ -742,10 +744,12 @@
/// expression From to the type ToType by following the standard
/// conversion sequence SCS. Returns true if there was an error, false
/// otherwise. The expression From is replaced with the converted
-/// expression.
+/// expression. Flavor is the context in which we're performing this
+/// conversion, for use in error messages.
bool
Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
- const StandardConversionSequence& SCS)
+ const StandardConversionSequence& SCS,
+ const char *Flavor)
{
// Overall FIXME: we are recomputing too many types here and doing
// far too much extra work. What this means is that we need to keep
@@ -808,6 +812,14 @@
break;
case ICK_Pointer_Conversion:
+ if (SCS.IncompatibleObjC) {
+ // Diagnose incompatible Objective-C conversions
+ Diag(From->getSourceRange().getBegin(),
+ diag::ext_typecheck_convert_incompatible_pointer)
+ << From->getType() << ToType << Flavor
+ << From->getSourceRange();
+ }
+
if (CheckPointerConversion(From, ToType))
return true;
ImpCastExprToType(From, ToType);