]> granicus.if.org Git - clang/commitdiff
Allow unavailable function calls inside unavailable functions in C++/ObjC++ as well...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 23 Jun 2011 00:41:50 +0000 (00:41 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 23 Jun 2011 00:41:50 +0000 (00:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133672 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaOverload.cpp
test/SemaCXX/attr-unavailable.cpp

index 074207cb55764d458cb8cbf3bf0f233657ec9766..142b1563be2e75cd6de86edff84260088adea04d 100644 (file)
@@ -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,
index eb1d661183accb8aac5dac6f16c154cf5b4d8acc..944d4813183a559fa430e2080131a930e4a20115 100644 (file)
@@ -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<Decl>(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);
 
index 5f34ed9904135fa3e34eaababed0a6f9f94dcc0c..2d82668a205a33289a38b9c26c19b1c661f928df 100644 (file)
@@ -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();
+}