From: Argyrios Kyrtzidis Date: Thu, 23 Jun 2011 00:41:50 +0000 (+0000) Subject: Allow unavailable function calls inside unavailable functions in C++/ObjC++ as well... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=572bbec2e0e23f684108e3a410a67c8c60ff9179;p=clang Allow unavailable function calls inside unavailable functions in C++/ObjC++ as well. rdar://9660196 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133672 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 074207cb55..142b1563be 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1315,6 +1315,13 @@ public: bool IsForUsingDecl); bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl); + /// \brief Checks availability of the function depending on the current + /// function context.Inside an unavailable function,unavailability is ignored. + /// + /// \returns true if \arg FD is unavailable and current context is inside + /// an available function, false otherwise. + bool isFunctionConsideredUnavailable(FunctionDecl *FD); + ImplicitConversionSequence TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index eb1d661183..944d481318 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -736,6 +736,15 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, return false; } +/// \brief Checks availability of the function depending on the current +/// function context. Inside an unavailable function, unavailability is ignored. +/// +/// \returns true if \arg FD is unavailable and current context is inside +/// an available function, false otherwise. +bool Sema::isFunctionConsideredUnavailable(FunctionDecl *FD) { + return FD->isUnavailable() && !cast(CurContext)->isUnavailable(); +} + /// TryImplicitConversion - Attempt to perform an implicit conversion /// from the given expression (Expr) to the given type (ToType). This /// function returns an implicit conversion sequence that can be used @@ -6592,7 +6601,8 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, // Best is the best viable function. if (Best->Function && - (Best->Function->isDeleted() || Best->Function->isUnavailable())) + (Best->Function->isDeleted() || + S.isFunctionConsideredUnavailable(Best->Function))) return OR_Deleted; return OR_Success; @@ -7087,7 +7097,8 @@ void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, FunctionDecl *Fn = Cand->Function; // Note deleted candidates, but only if they're viable. - if (Cand->Viable && (Fn->isDeleted() || Fn->isUnavailable())) { + if (Cand->Viable && (Fn->isDeleted() || + S.isFunctionConsideredUnavailable(Fn))) { std::string FnDesc; OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc); diff --git a/test/SemaCXX/attr-unavailable.cpp b/test/SemaCXX/attr-unavailable.cpp index 5f34ed9904..2d82668a20 100644 --- a/test/SemaCXX/attr-unavailable.cpp +++ b/test/SemaCXX/attr-unavailable.cpp @@ -28,3 +28,12 @@ void bar() { foo(); // expected-error {{call to unavailable function 'foo': not available - replaced}} } } + +void unavail(short* sp) __attribute__((__unavailable__)); +void unavail(short* sp) { + // No complains inside an unavailable function. + int &ir = foo(1); + double &dr = foo(1.0); + foo(sp); + foo(); +}