summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaCast.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-10-11 23:14:30 +0000
committerJohn McCall <rjmccall@apple.com>2011-10-11 23:14:30 +0000
commit6dbba4fc128e2e2f5b26be996392bd32c0707f13 (patch)
tree39387293b950b16aa176d75fe9d5b3201e0b56e8 /lib/Sema/SemaCast.cpp
parent336c8f70ff961c5568de3b9c65fb0502843b7407 (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.cpp44
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;
}