[cfe-commits] r122295 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaOverload.cpp
John McCall
rjmccall at apple.com
Mon Dec 20 16:44:39 PST 2010
Author: rjmccall
Date: Mon Dec 20 18:44:39 2010
New Revision: 122295
URL: http://llvm.org/viewvc/llvm-project?rev=122295&view=rev
Log:
Fix the noreturn conversion to only strip off a single level of indirection.
Apply the noreturn attribute while creating a builtin function's type.
Remove the getNoReturnType() API.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=122295&r1=122294&r2=122295&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Dec 20 18:44:39 2010
@@ -484,11 +484,6 @@
const FunctionType *adjustFunctionType(const FunctionType *Fn,
FunctionType::ExtInfo EInfo);
- /// getNoReturnType - Add or remove the noreturn attribute to the given type
- /// which must be a FunctionType or a pointer to an allowable type or a
- /// BlockPointer.
- QualType getNoReturnType(QualType T, bool AddNoReturn = true);
-
/// getComplexType - Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType getComplexType(QualType T);
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=122295&r1=122294&r2=122295&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Dec 20 18:44:39 2010
@@ -1159,53 +1159,6 @@
return cast<FunctionType>(Result.getTypePtr());
}
-static QualType getExtFunctionType(ASTContext& Context, QualType T,
- FunctionType::ExtInfo Info) {
- QualType ResultType;
- if (const PointerType *Pointer = T->getAs<PointerType>()) {
- QualType Pointee = Pointer->getPointeeType();
- ResultType = getExtFunctionType(Context, Pointee, Info);
- if (ResultType == Pointee)
- return T;
-
- ResultType = Context.getPointerType(ResultType);
- } else if (const ParenType *Paren = T->getAs<ParenType>()) {
- QualType Inner = Paren->getInnerType();
- ResultType = getExtFunctionType(Context, Inner, Info);
- if (ResultType == Inner)
- return T;
-
- ResultType = Context.getParenType(ResultType);
- } else if (const BlockPointerType *BlockPointer
- = T->getAs<BlockPointerType>()) {
- QualType Pointee = BlockPointer->getPointeeType();
- ResultType = getExtFunctionType(Context, Pointee, Info);
- if (ResultType == Pointee)
- return T;
-
- ResultType = Context.getBlockPointerType(ResultType);
- } else if (const MemberPointerType *MemberPointer
- = T->getAs<MemberPointerType>()) {
- QualType Pointee = MemberPointer->getPointeeType();
- ResultType = getExtFunctionType(Context, Pointee, Info);
- if (ResultType == Pointee)
- return T;
-
- ResultType = Context.getMemberPointerType(ResultType,
- MemberPointer->getClass());
- } else if (const FunctionType *F = T->getAs<FunctionType>()) {
- ResultType = QualType(Context.adjustFunctionType(F, Info), 0);
- } else
- return T;
-
- return Context.getQualifiedType(ResultType, T.getLocalQualifiers());
-}
-
-QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) {
- FunctionType::ExtInfo Info = getFunctionExtInfo(T);
- return getExtFunctionType(*this, T, Info.withNoReturn(AddNoReturn));
-}
-
/// getComplexType - Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType ASTContext::getComplexType(QualType T) {
@@ -5595,13 +5548,18 @@
assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
"'.' should only occur at end of builtin type list!");
- // handle untyped/variadic arguments "T c99Style();" or "T cppStyle(...);".
- if (ArgTypes.size() == 0 && TypeStr[0] == '.')
- return getFunctionNoProtoType(ResType);
+ FunctionType::ExtInfo EI;
+ if (BuiltinInfo.isNoReturn(Id)) EI = EI.withNoReturn(true);
+
+ bool Variadic = (TypeStr[0] == '.');
+
+ // We really shouldn't be making a no-proto type here, especially in C++.
+ if (ArgTypes.empty() && Variadic)
+ return getFunctionNoProtoType(ResType, EI);
FunctionProtoType::ExtProtoInfo EPI;
- EPI.Variadic = (TypeStr[0] == '.');
- // FIXME: Should we create noreturn types?
+ EPI.ExtInfo = EI;
+ EPI.Variadic = Variadic;
return getFunctionType(ResType, ArgTypes.data(), ArgTypes.size(), EPI);
}
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=122295&r1=122294&r2=122295&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Dec 20 18:44:39 2010
@@ -5594,8 +5594,6 @@
FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
}
- if (Context.BuiltinInfo.isNoReturn(BuiltinID))
- FD->setType(Context.getNoReturnType(FD->getType()));
if (Context.BuiltinInfo.isNoThrow(BuiltinID))
FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context));
if (Context.BuiltinInfo.isConst(BuiltinID))
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=122295&r1=122294&r2=122295&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Dec 20 18:44:39 2010
@@ -882,13 +882,44 @@
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;
+ // Permit the conversion F(t __attribute__((noreturn))) -> F(t)
+ // where F adds one of the following at most once:
+ // - a pointer
+ // - a member pointer
+ // - a block pointer
+ CanQualType CanTo = Context.getCanonicalType(ToType);
+ CanQualType CanFrom = Context.getCanonicalType(FromType);
+ Type::TypeClass TyClass = CanTo->getTypeClass();
+ if (TyClass != CanFrom->getTypeClass()) return false;
+ if (TyClass != Type::FunctionProto && TyClass != Type::FunctionNoProto) {
+ if (TyClass == Type::Pointer) {
+ CanTo = CanTo.getAs<PointerType>()->getPointeeType();
+ CanFrom = CanFrom.getAs<PointerType>()->getPointeeType();
+ } else if (TyClass == Type::BlockPointer) {
+ CanTo = CanTo.getAs<BlockPointerType>()->getPointeeType();
+ CanFrom = CanFrom.getAs<BlockPointerType>()->getPointeeType();
+ } else if (TyClass == Type::MemberPointer) {
+ CanTo = CanTo.getAs<MemberPointerType>()->getPointeeType();
+ CanFrom = CanFrom.getAs<MemberPointerType>()->getPointeeType();
+ } else {
+ return false;
+ }
+
+ TyClass = CanTo->getTypeClass();
+ if (TyClass != CanFrom->getTypeClass()) return false;
+ if (TyClass != Type::FunctionProto && TyClass != Type::FunctionNoProto)
+ return false;
+ }
+
+ const FunctionType *FromFn = cast<FunctionType>(CanFrom);
+ FunctionType::ExtInfo EInfo = FromFn->getExtInfo();
+ if (!EInfo.getNoReturn()) return false;
+
+ FromFn = Context.adjustFunctionType(FromFn, EInfo.withNoReturn(false));
+ assert(QualType(FromFn, 0).isCanonical());
+ if (QualType(FromFn, 0) != CanTo) return false;
- ResultTy = FromType;
+ ResultTy = ToType;
return true;
}
More information about the cfe-commits
mailing list