From c910d4cfa5042f2c9da1eb4e0b6ed59240c0eeee Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Sat, 8 Jun 2013 18:19:52 +0000 Subject: [PATCH] Revert "[Sema] Make FunctionType's TSI use unadjusted argument types" This reverts commit r183614. It broke test/Sema/block-printf-attribute-1.c on non-Windows platforms, and the fix is not trivial. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183616 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTContext.h | 2 +- lib/AST/ASTContext.cpp | 15 -------- lib/AST/Type.cpp | 6 +-- lib/Sema/SemaDecl.cpp | 67 ++++++++++++++++------------------ lib/Sema/SemaType.cpp | 10 +++-- test/Index/print-type.c | 2 +- test/Index/print-type.cpp | 2 +- test/Sema/function-redecl.c | 5 --- 8 files changed, 42 insertions(+), 67 deletions(-) diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 553df517b8..324185f090 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -1465,7 +1465,7 @@ public: /// /// \pre Neither type.ObjCLifetime() nor \p lifetime may be \c OCL_None. QualType getLifetimeQualifiedType(QualType type, - Qualifiers::ObjCLifetime lifetime) const { + Qualifiers::ObjCLifetime lifetime) { assert(type.getObjCLifetime() == Qualifiers::OCL_None); assert(lifetime != Qualifiers::OCL_None); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 384164167d..44ff94e358 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4142,21 +4142,6 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const { } QualType ASTContext::getAdjustedParameterType(QualType T) const { - // In ARC, infer a lifetime qualifier for appropriate parameter types. - if (getLangOpts().ObjCAutoRefCount && - T.getObjCLifetime() == Qualifiers::OCL_None && - T->isObjCLifetimeType()) { - // Special cases for arrays: - // - if it's const, use __unsafe_unretained - // - otherwise, it's an error - Qualifiers::ObjCLifetime lifetime; - if (T->isArrayType()) - lifetime = Qualifiers::OCL_ExplicitNone; - else - lifetime = T->getObjCARCImplicitLifetime(); - T = getLifetimeQualifiedType(T, lifetime); - } - // C99 6.7.5.3p7: // A declaration of a parameter as "array of type" shall be // adjusted to "qualified pointer to type", where the type diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 2c5233bce6..c32df11b66 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1781,10 +1781,8 @@ bool TypeOfExprType::isSugared() const { } QualType TypeOfExprType::desugar() const { - if (isSugared()) { - Expr *E = getUnderlyingExpr(); - return E->getType(); - } + if (isSugared()) + return getUnderlyingExpr()->getType(); return QualType(this, 0); } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 1db768b28a..e6a89461b4 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5897,40 +5897,23 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, << DeclSpec::getSpecifierName(TSCS); // Do not allow returning a objc interface by-value. - bool NeedsAdjustment = false; - const FunctionType *FT = R->castAs(); - QualType ResultTy = FT->getResultType(); - if (ResultTy->isObjCObjectType()) { + if (R->getAs()->getResultType()->isObjCObjectType()) { Diag(D.getIdentifierLoc(), - diag::err_object_cannot_be_passed_returned_by_value) << 0 << ResultTy - << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*"); - ResultTy = Context.getObjCObjectPointerType(ResultTy); - NeedsAdjustment = true; - } - - // Adjust parameter types from the type as written. - SmallVector AdjustedParms; - const FunctionProtoType *FPT = dyn_cast(FT); - if (FPT) { - for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(), - E = FPT->arg_type_end(); I != E; ++I) { - AdjustedParms.push_back(Context.getAdjustedParameterType(*I)); - if (AdjustedParms.back() != *I) - NeedsAdjustment = true; - } - } + diag::err_object_cannot_be_passed_returned_by_value) << 0 + << R->getAs()->getResultType() + << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*"); - // Skip the type recreation if it isn't needed, for performance and to avoid - // prematurely desugaring things like typedefs and __typeofs. - if (NeedsAdjustment) { - if (FPT) { + QualType T = R->getAs()->getResultType(); + T = Context.getObjCObjectPointerType(T); + if (const FunctionProtoType *FPT = dyn_cast(R)) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - R = Context.getFunctionType(ResultTy, AdjustedParms, EPI); - } else { - assert(isa(FT)); - FunctionType::ExtInfo EI = FT->getExtInfo(); - R = Context.getFunctionNoProtoType(ResultTy, EI); + R = Context.getFunctionType(T, + ArrayRef(FPT->arg_type_begin(), + FPT->getNumArgs()), + EPI); } + else if (isa(R)) + R = Context.getFunctionNoProtoType(T); } bool isFriend = false; @@ -8515,15 +8498,27 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, IdentifierInfo *Name, QualType T, TypeSourceInfo *TSInfo, VarDecl::StorageClass StorageClass) { - // Diagnose non-const parameter arrays of ARC types. + // In ARC, infer a lifetime qualifier for appropriate parameter types. if (getLangOpts().ObjCAutoRefCount && T.getObjCLifetime() == Qualifiers::OCL_None && - T->isObjCLifetimeType() && - T->isArrayType() && - !T.isConstQualified()) { - DelayedDiagnostics.add( - sema::DelayedDiagnostic::makeForbiddenType( + T->isObjCLifetimeType()) { + + Qualifiers::ObjCLifetime lifetime; + + // Special cases for arrays: + // - if it's const, use __unsafe_unretained + // - otherwise, it's an error + if (T->isArrayType()) { + if (!T.isConstQualified()) { + DelayedDiagnostics.add( + sema::DelayedDiagnostic::makeForbiddenType( NameLoc, diag::err_arc_array_param_no_ownership, T, false)); + } + lifetime = Qualifiers::OCL_ExplicitNone; + } else { + lifetime = T->getObjCARCImplicitLifetime(); + } + T = Context.getLifetimeQualifiedType(T, lifetime); } ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name, diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 977294bd46..e27d627d3f 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1674,7 +1674,7 @@ QualType Sema::BuildFunctionType(QualType T, bool Invalid = false; for (unsigned Idx = 0, Cnt = ParamTypes.size(); Idx < Cnt; ++Idx) { // FIXME: Loc is too inprecise here, should use proper locations for args. - QualType ParamType = ParamTypes[Idx]; + QualType ParamType = Context.getAdjustedParameterType(ParamTypes[Idx]); if (ParamType->isVoidType()) { Diag(Loc, diag::err_param_with_void_type); Invalid = true; @@ -2798,11 +2798,13 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) { ParmVarDecl *Param = cast(FTI.ArgInfo[i].Param); - // Get the type as written. It will be adjusted later in - // ActOnFunctionDeclarator(). - QualType ArgTy = Param->getTypeSourceInfo()->getType(); + QualType ArgTy = Param->getType(); assert(!ArgTy.isNull() && "Couldn't parse type?"); + // Adjust the parameter type. + assert((ArgTy == Context.getAdjustedParameterType(ArgTy)) && + "Unadjusted type?"); + // Look for 'void'. void is allowed only as a single argument to a // function with no other parameters (C99 6.7.5.3p10). We record // int(void) as a FunctionProtoType with an empty argument list. diff --git a/test/Index/print-type.c b/test/Index/print-type.c index 5fc28ab605..4805f59f3f 100644 --- a/test/Index/print-type.c +++ b/test/Index/print-type.c @@ -11,7 +11,7 @@ int __attribute__((vector_size(16))) x; typedef int __attribute__((vector_size(16))) int4_t; // RUN: c-index-test -test-print-type %s | FileCheck %s -// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int [5], void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int [5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0] +// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int [5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0] // CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] // CHECK: ParmDecl=x:3:22 (Definition) [type=char *] [typekind=Pointer] [isPOD=1] // CHECK: ParmDecl=z:3:33 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] diff --git a/test/Index/print-type.cpp b/test/Index/print-type.cpp index 0f62826225..49a05fbbdb 100644 --- a/test/Index/print-type.cpp +++ b/test/Index/print-type.cpp @@ -62,5 +62,5 @@ T tbar(int[5]); // CHECK: TypedefDecl=ArrayType:20:15 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1] // CHECK: FunctionTemplate=tbar:27:3 [type=T (int)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0] // CHECK: TemplateTypeParameter=T:26:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0] -// CHECK: FunctionTemplate=tbar:30:3 [type=T (int [5])] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0] +// CHECK: FunctionTemplate=tbar:30:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0] // CHECK: ParmDecl=:30:11 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1] diff --git a/test/Sema/function-redecl.c b/test/Sema/function-redecl.c index a43dfc3de3..561f7fae6b 100644 --- a/test/Sema/function-redecl.c +++ b/test/Sema/function-redecl.c @@ -115,11 +115,6 @@ void i0 (unsigned short a0); extern __typeof (i0) i1; extern __typeof (i1) i1; -// Try __typeof with a parameter that needs adjustment. -void j0 (int a0[1], ...); -extern __typeof (j0) j1; -extern __typeof (j1) j1; - typedef int a(); typedef int a2(int*); a x; -- 2.40.0