From 131996b1697d440aa52250c7ec3f089c092b2a42 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 31 Jul 2013 18:21:45 +0000 Subject: [PATCH] ObjectiveC arc: Introduce a new initialization kind for parameters passed to CF audited functions to be used for better diagnostics. Current set but unused. // rdar://14569171 llvm-svn: 187508 --- clang/include/clang/Sema/Initialization.h | 15 +++++++++++++-- clang/lib/Sema/SemaExpr.cpp | 6 ++++++ clang/lib/Sema/SemaInit.cpp | 28 +++++++++++++++++++--------- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index cd11fce..1f3c869 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -82,7 +82,10 @@ public: EK_CompoundLiteralInit, /// \brief The entity being implicitly initialized back to the formal /// result type. - EK_RelatedResult + EK_RelatedResult, + /// \brief The entity being initialized is a function parameter; function + /// is member of group of audited CF APIs. + EK_Parameter_CF_Audited }; private: @@ -351,10 +354,14 @@ public: /// value optimization, which also applies to thrown objects. bool allowsNRVO() const; + bool isParameterKind() const { + return (getKind() == EK_Parameter || + getKind() == EK_Parameter_CF_Audited); + } /// \brief Determine whether this initialization consumes the /// parameter. bool isParameterConsumed() const { - assert(getKind() == EK_Parameter && "Not a parameter"); + assert(isParameterKind() && "Not a parameter"); return (Parameter & 1); } @@ -404,6 +411,10 @@ public: assert(getKind() == EK_LambdaCapture && "Not a lambda capture!"); return SourceLocation::getFromRawEncoding(Capture.Location); } + + void setParameterCFAudited() { + Kind = EK_Parameter_CF_Audited; + } /// Dump a representation of the initialized entity to standard error, /// for debugging purposes. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4397fb7..2fbda8e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4070,6 +4070,12 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, InitializedEntity::InitializeParameter(Context, Param, ProtoArgType) : InitializedEntity::InitializeParameter(Context, ProtoArgType, Proto->isArgConsumed(i)); + + // Remember that parameter belongs to a CF audited API. + if (FDecl && FDecl->hasAttr() && + (!Param || !Param->hasAttr())) + Entity.setParameterCFAudited(); + ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), Owned(Arg), diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index ce86125..2708767 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -2472,7 +2472,8 @@ InitializedEntity::InitializeBase(ASTContext &Context, DeclarationName InitializedEntity::getName() const { switch (getKind()) { - case EK_Parameter: { + case EK_Parameter: + case EK_Parameter_CF_Audited: { ParmVarDecl *D = reinterpret_cast(Parameter & ~0x1); return (D ? D->getDeclName() : DeclarationName()); } @@ -2509,6 +2510,7 @@ DeclaratorDecl *InitializedEntity::getDecl() const { return VariableOrMember; case EK_Parameter: + case EK_Parameter_CF_Audited: return reinterpret_cast(Parameter & ~0x1); case EK_Result: @@ -2538,6 +2540,7 @@ bool InitializedEntity::allowsNRVO() const { case EK_Variable: case EK_Parameter: + case EK_Parameter_CF_Audited: case EK_Member: case EK_New: case EK_Temporary: @@ -2565,6 +2568,8 @@ unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const { switch (getKind()) { case EK_Variable: OS << "Variable"; break; case EK_Parameter: OS << "Parameter"; break; + case EK_Parameter_CF_Audited: OS << "CF audited function Parameter"; + break; case EK_Result: OS << "Result"; break; case EK_Exception: OS << "Exception"; break; case EK_Member: OS << "Member"; break; @@ -2920,7 +2925,7 @@ static void MaybeProduceObjCObject(Sema &S, /// When initializing a parameter, produce the value if it's marked /// __attribute__((ns_consumed)). - if (Entity.getKind() == InitializedEntity::EK_Parameter) { + if (Entity.isParameterKind()) { if (!Entity.isParameterConsumed()) return; @@ -4493,7 +4498,7 @@ InitializationSequence::InitializationSequence(Sema &S, // Determine whether we should consider writeback conversions for // Objective-C ARC. bool allowObjCWritebackConversion = S.getLangOpts().ObjCAutoRefCount && - Entity.getKind() == InitializedEntity::EK_Parameter; + Entity.isParameterKind(); // We're at the end of the line for C: it's either a write-back conversion // or it's a C assignment. There's no need to check anything else. @@ -4629,6 +4634,7 @@ getAssignmentAction(const InitializedEntity &Entity) { return Sema::AA_Initializing; case InitializedEntity::EK_Parameter: + case InitializedEntity::EK_Parameter_CF_Audited: if (Entity.getDecl() && isa(Entity.getDecl()->getDeclContext())) return Sema::AA_Sending; @@ -4676,6 +4682,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) { return false; case InitializedEntity::EK_Parameter: + case InitializedEntity::EK_Parameter_CF_Audited: case InitializedEntity::EK_Temporary: case InitializedEntity::EK_RelatedResult: return true; @@ -4701,6 +4708,7 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) { case InitializedEntity::EK_Member: case InitializedEntity::EK_Variable: case InitializedEntity::EK_Parameter: + case InitializedEntity::EK_Parameter_CF_Audited: case InitializedEntity::EK_Temporary: case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_Exception: @@ -4780,6 +4788,7 @@ static SourceLocation getInitializationLoc(const InitializedEntity &Entity, case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_Member: case InitializedEntity::EK_Parameter: + case InitializedEntity::EK_Parameter_CF_Audited: case InitializedEntity::EK_Temporary: case InitializedEntity::EK_New: case InitializedEntity::EK_Base: @@ -4999,7 +5008,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S, void InitializationSequence::PrintInitLocationNote(Sema &S, const InitializedEntity &Entity) { - if (Entity.getKind() == InitializedEntity::EK_Parameter && Entity.getDecl()) { + if (Entity.isParameterKind() && Entity.getDecl()) { if (Entity.getDecl()->getLocation().isInvalid()) return; @@ -5197,6 +5206,7 @@ InitializedEntityOutlivesFullExpression(const InitializedEntity &Entity) { return false; case InitializedEntity::EK_Parameter: + case InitializedEntity::EK_Parameter_CF_Audited: case InitializedEntity::EK_Temporary: case InitializedEntity::EK_LambdaCapture: case InitializedEntity::EK_CompoundLiteralInit: @@ -5232,6 +5242,7 @@ getDeclForTemporaryLifetimeExtension(const InitializedEntity &Entity, return Entity.getDecl(); case InitializedEntity::EK_Parameter: + case InitializedEntity::EK_Parameter_CF_Audited: // -- A temporary bound to a reference parameter in a function call // persists until the completion of the full-expression containing // the call. @@ -5484,7 +5495,7 @@ InitializationSequence::Perform(Sema &S, if (S.getLangOpts().CPlusPlus11 && Entity.getType()->isReferenceType() && Args.size() == 1 && isa(Args[0]) && - Entity.getKind() != InitializedEntity::EK_Parameter) { + !Entity.isParameterKind()) { // Produce a C++98 compatibility warning if we are initializing a reference // from an initializer list. For parameters, we produce a better warning // elsewhere. @@ -5976,7 +5987,7 @@ InitializationSequence::Perform(Sema &S, // If this is a call, allow conversion to a transparent union. ExprResult CurInitExprRes = CurInit; if (ConvTy != Sema::Compatible && - Entity.getKind() == InitializedEntity::EK_Parameter && + Entity.isParameterKind() && S.CheckTransparentUnionArgumentConstraints(Step->Type, CurInitExprRes) == Sema::Compatible) ConvTy = Sema::Compatible; @@ -6089,13 +6100,12 @@ InitializationSequence::Perform(Sema &S, "Sampler initialization on non sampler type."); QualType SourceType = CurInit.get()->getType(); - InitializedEntity::EntityKind EntityKind = Entity.getKind(); - if (EntityKind == InitializedEntity::EK_Parameter) { + if (Entity.isParameterKind()) { if (!SourceType->isSamplerT()) S.Diag(Kind.getLocation(), diag::err_sampler_argument_required) << SourceType; - } else if (EntityKind != InitializedEntity::EK_Variable) { + } else if (Entity.getKind() != InitializedEntity::EK_Variable) { llvm_unreachable("Invalid EntityKind!"); } -- 2.7.4