aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-12-09 00:47:37 +0000
committerDouglas Gregor <dgregor@apple.com>2009-12-09 00:47:37 +0000
commit43c79c2b07abc7ba6d9f243b84ee6539de4d2652 (patch)
tree790ec22e1b69c168ef89a885b2c4cf1c2a425f36 /lib/Sema/SemaOverload.cpp
parenta498ca67b3d6bb65443c00ef8aa8e3c83ef19b6d (diff)
Implemented an implicit conversion from "noreturn" function types (and
pointers thereof) to their corresponding non-noreturn function types. This conversion is considered an exact match for overload-resolution purposes. Note that we are a little more strict that GCC is, because we encode noreturn in the type system, but that's a Good Thing (TM) because it does not allow us to pretend that potentially-returning function pointers are non-returning function pointers. Fxies PR5620. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90913 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp32
1 files changed, 29 insertions, 3 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 769adb51cf..47393f7b23 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -38,6 +38,7 @@ GetConversionCategory(ImplicitConversionKind Kind) {
ICC_Lvalue_Transformation,
ICC_Lvalue_Transformation,
ICC_Lvalue_Transformation,
+ ICC_Identity,
ICC_Qualification_Adjustment,
ICC_Promotion,
ICC_Promotion,
@@ -66,6 +67,7 @@ ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind) {
ICR_Exact_Match,
ICR_Exact_Match,
ICR_Exact_Match,
+ ICR_Exact_Match,
ICR_Promotion,
ICR_Promotion,
ICR_Promotion,
@@ -91,6 +93,7 @@ const char* GetImplicitConversionName(ImplicitConversionKind Kind) {
"Lvalue-to-rvalue",
"Array-to-pointer",
"Function-to-pointer",
+ "Noreturn adjustment",
"Qualification",
"Integral promotion",
"Floating point promotion",
@@ -475,6 +478,23 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
return ICS;
}
+/// \brief Determine whether the conversion from FromType to ToType is a valid
+/// conversion that strips "noreturn" off the nested function type.
+static bool IsNoReturnConversion(ASTContext &Context, QualType FromType,
+ QualType ToType, QualType &ResultTy) {
+ if (Context.hasSameUnqualifiedType(FromType, ToType))
+ return false;
+
+ // Strip the noreturn off the type we're converting from; noreturn can
+ // safely be removed.
+ FromType = Context.getNoReturnType(FromType, false);
+ if (!Context.hasSameUnqualifiedType(FromType, ToType))
+ return false;
+
+ ResultTy = FromType;
+ return true;
+}
+
/// IsStandardConversion - Determines whether there is a standard
/// conversion sequence (C++ [conv], C++ [over.ics.scs]) from the
/// expression From to the type ToType. Standard conversion sequences
@@ -554,7 +574,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// function. (C++ 4.3p1).
FromType = Context.getPointerType(FromType);
} else if (FunctionDecl *Fn
- = ResolveAddressOfOverloadedFunction(From, ToType, false)) {
+ = ResolveAddressOfOverloadedFunction(From, ToType, false)) {
// Address of overloaded function (C++ [over.over]).
SCS.First = ICK_Function_To_Pointer;
@@ -656,6 +676,9 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
Context.typesAreCompatible(ToType, FromType)) {
// Compatible conversions (Clang extension for C function overloading)
SCS.Second = ICK_Compatible_Conversion;
+ } else if (IsNoReturnConversion(Context, FromType, ToType, FromType)) {
+ // Treat a conversion that strips "noreturn" as an identity conversion.
+ SCS.Second = ICK_NoReturn_Adjustment;
} else {
// No second conversion required.
SCS.Second = ICK_Identity;
@@ -1234,7 +1257,7 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType,
return false;
}
-
+
/// CheckMemberPointerConversion - Check the member pointer conversion from the
/// expression From to the type ToType. This routine checks for ambiguous or
/// virtual (FIXME: or inaccessible) base-to-derived member pointer conversions
@@ -4455,7 +4478,10 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
continue;
if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*I)) {
- if (FunctionType == Context.getCanonicalType(FunDecl->getType())) {
+ QualType ResultTy;
+ if (Context.hasSameUnqualifiedType(FunctionType, FunDecl->getType()) ||
+ IsNoReturnConversion(Context, FunDecl->getType(), FunctionType,
+ ResultTy)) {
Matches.insert(cast<FunctionDecl>(FunDecl->getCanonicalDecl()));
FoundNonTemplateFunction = true;
}