diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-12-09 00:47:37 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-12-09 00:47:37 +0000 |
commit | 43c79c2b07abc7ba6d9f243b84ee6539de4d2652 (patch) | |
tree | 790ec22e1b69c168ef89a885b2c4cf1c2a425f36 /lib/AST/ASTContext.cpp | |
parent | a498ca67b3d6bb65443c00ef8aa8e3c83ef19b6d (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/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 490f338d38..fcdd48716e 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1200,32 +1200,42 @@ QualType ASTContext::getObjCGCQualType(QualType T, return getExtQualType(TypeNode, Quals); } -QualType ASTContext::getNoReturnType(QualType T) { +QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) { QualType ResultType; - if (T->isPointerType()) { - QualType Pointee = T->getAs<PointerType>()->getPointeeType(); - ResultType = getNoReturnType(Pointee); + if (const PointerType *Pointer = T->getAs<PointerType>()) { + QualType Pointee = Pointer->getPointeeType(); + ResultType = getNoReturnType(Pointee, AddNoReturn); + if (ResultType == Pointee) + return T; + ResultType = getPointerType(ResultType); - } else if (T->isBlockPointerType()) { - QualType Pointee = T->getAs<BlockPointerType>()->getPointeeType(); - ResultType = getNoReturnType(Pointee); + } else if (const BlockPointerType *BlockPointer + = T->getAs<BlockPointerType>()) { + QualType Pointee = BlockPointer->getPointeeType(); + ResultType = getNoReturnType(Pointee, AddNoReturn); + if (ResultType == Pointee) + return T; + ResultType = getBlockPointerType(ResultType); - } else { - assert (T->isFunctionType() - && "can't noreturn qualify non-pointer to function or block type"); - - if (const FunctionNoProtoType *FNPT = T->getAs<FunctionNoProtoType>()) { - ResultType = getFunctionNoProtoType(FNPT->getResultType(), true); + } else if (const FunctionType *F = T->getAs<FunctionType>()) { + if (F->getNoReturnAttr() == AddNoReturn) + return T; + + if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(F)) { + ResultType = getFunctionNoProtoType(FNPT->getResultType(), AddNoReturn); } else { - const FunctionProtoType *F = T->getAs<FunctionProtoType>(); + const FunctionProtoType *FPT = cast<FunctionProtoType>(F); ResultType - = getFunctionType(F->getResultType(), F->arg_type_begin(), - F->getNumArgs(), F->isVariadic(), F->getTypeQuals(), - F->hasExceptionSpec(), F->hasAnyExceptionSpec(), - F->getNumExceptions(), F->exception_begin(), true); + = getFunctionType(FPT->getResultType(), FPT->arg_type_begin(), + FPT->getNumArgs(), FPT->isVariadic(), + FPT->getTypeQuals(), + FPT->hasExceptionSpec(), FPT->hasAnyExceptionSpec(), + FPT->getNumExceptions(), FPT->exception_begin(), + AddNoReturn); } - } - + } else + return T; + return getQualifiedType(ResultType, T.getLocalQualifiers()); } |