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 | 40cb9ad391af6811c691e308764c3515a413c806 (patch) | |
| tree | 21159e8266168260aa58a7626fa9dc34b2d554d7 /clang/lib/AST/ASTContext.cpp | |
| parent | 4b2a6e200f0836e7fcbc3f8a7416648c2b2929d0 (diff) | |
| download | bcm5719-llvm-40cb9ad391af6811c691e308764c3515a413c806.tar.gz bcm5719-llvm-40cb9ad391af6811c691e308764c3515a413c806.zip | |
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.
llvm-svn: 90913
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 490f338d38f..fcdd48716e8 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/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()); } |

