Catch placeholder types in DefaultLvalueConversion
and DefaultFunctionArrayLvalueConversion.  To prevent
significant regression for should-this-be-a-call fixits,
and to repair some such regression from the introduction of
bound member placeholders, make those placeholder checks
try to build calls appropriately.  Harden the build-a-call
logic while we're at it.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141738 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index df9ef4f..8bd9351 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -49,7 +49,7 @@
       : Self(S), SrcExpr(src), DestType(destType),
         ResultType(destType.getNonLValueExprType(S.Context)),
         ValueKind(Expr::getValueKindForType(destType)),
-        Kind(CK_Dependent), IsARCUnbridgedCast(false) {
+        Kind(CK_Dependent) {
 
       if (const BuiltinType *placeholder =
             src.get()->getType()->getAsPlaceholderType()) {
@@ -65,7 +65,6 @@
     QualType ResultType;
     ExprValueKind ValueKind;
     CastKind Kind;
-    bool IsARCUnbridgedCast;
     BuiltinType::Kind PlaceholderKind;
     CXXCastPath BasePath;
 
@@ -639,7 +638,7 @@
 /// const char *str = "literal";
 /// legacy_function(const_cast\<char*\>(str));
 void CastOperation::CheckConstCast() {
-  if (ValueKind == VK_RValue) {
+  if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload)) {
     SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
     if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
       return;
@@ -658,7 +657,7 @@
 /// like this:
 /// char *bytes = reinterpret_cast\<char*\>(int_ptr);
 void CastOperation::CheckReinterpretCast() {
-  if (ValueKind == VK_RValue) {
+  if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload)) {
     SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
     if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
       return;
@@ -705,20 +704,20 @@
     Kind = CK_ToVoid;
 
     if (claimPlaceholder(BuiltinType::Overload)) {
-      ExprResult SingleFunctionExpression = 
-        Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr.get(), 
+      Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr, 
                 false, // Decay Function to ptr 
                 true, // Complain
                 OpRange, DestType, diag::err_bad_static_cast_overload);
-      if (SingleFunctionExpression.isUsable())
-        SrcExpr = SingleFunctionExpression;
+      if (SrcExpr.isInvalid())
+        return;
     }
 
     SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
     return;
   }
 
-  if (ValueKind == VK_RValue && !DestType->isRecordType()) {
+  if (ValueKind == VK_RValue && !DestType->isRecordType() &&
+      !isPlaceholder(BuiltinType::Overload)) {
     SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
     if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
       return;
@@ -1458,17 +1457,19 @@
   // Is the source an overloaded name? (i.e. &foo)
   // If so, reinterpret_cast can not help us here (13.4, p1, bullet 5) ...
   if (SrcType == Self.Context.OverloadTy) {
-    // ... unless foo<int> resolves to an lvalue unambiguously
-    ExprResult SingleFunctionExpr = 
-        Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr.get(), 
+    // ... unless foo<int> resolves to an lvalue unambiguously.
+    // TODO: what if this fails because of DiagnoseUseOfDecl or something
+    // like it?
+    ExprResult SingleFunctionExpr = SrcExpr;
+    if (Self.ResolveAndFixSingleFunctionTemplateSpecialization(
+          SingleFunctionExpr,
           Expr::getValueKindForType(DestType) == VK_RValue // Convert Fun to Ptr 
-        );
-    if (SingleFunctionExpr.isUsable()) {
+        ) && SingleFunctionExpr.isUsable()) {
       SrcExpr = move(SingleFunctionExpr);
       SrcType = SrcExpr.get()->getType();
-    }      
-    else  
+    } else {
       return TC_NotApplicable;
+    }
   }
 
   if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
@@ -1736,8 +1737,8 @@
     Kind = CK_ToVoid;
 
     if (claimPlaceholder(BuiltinType::Overload)) {
-      SrcExpr = Self.ResolveAndFixSingleFunctionTemplateSpecialization(
-                  SrcExpr.take(), /* Decay Function to ptr */ false, 
+      Self.ResolveAndFixSingleFunctionTemplateSpecialization(
+                  SrcExpr, /* Decay Function to ptr */ false, 
                   /* Complain */ true, DestRange, DestType,
                   diag::err_bad_cstyle_cast_overload);
       if (SrcExpr.isInvalid())
@@ -1757,7 +1758,8 @@
     return;
   }
 
-  if (ValueKind == VK_RValue && !DestType->isRecordType()) {
+  if (ValueKind == VK_RValue && !DestType->isRecordType() &&
+      !isPlaceholder(BuiltinType::Overload)) {
     SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
     if (SrcExpr.isInvalid())
       return;
@@ -1849,7 +1851,9 @@
       return;
     }
 
-    checkNonOverloadPlaceholders();
+    // We allow overloads in C, but we don't allow them to be resolved
+    // by anything except calls.
+    SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
     if (SrcExpr.isInvalid())
       return;
   }