diff options
author | John McCall <rjmccall@apple.com> | 2011-10-11 23:14:30 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-10-11 23:14:30 +0000 |
commit | 6dbba4fc128e2e2f5b26be996392bd32c0707f13 (patch) | |
tree | 39387293b950b16aa176d75fe9d5b3201e0b56e8 /lib/Sema/SemaCast.cpp | |
parent | 336c8f70ff961c5568de3b9c65fb0502843b7407 (diff) |
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
Diffstat (limited to 'lib/Sema/SemaCast.cpp')
-rw-r--r-- | lib/Sema/SemaCast.cpp | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index df9ef4f5bc..8bd9351e0b 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -49,7 +49,7 @@ namespace { : 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 @@ namespace { QualType ResultType; ExprValueKind ValueKind; CastKind Kind; - bool IsARCUnbridgedCast; BuiltinType::Kind PlaceholderKind; CXXCastPath BasePath; @@ -639,7 +638,7 @@ void CastOperation::CheckDynamicCast() { /// 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 @@ void CastOperation::CheckConstCast() { /// 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 @@ void CastOperation::CheckStaticCast() { 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 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, // 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 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) { 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 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) { 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 @@ void CastOperation::CheckCStyleCast() { 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; } |