r262921 - Sema: Methods in unavailable classes are unavailable
Duncan P. N. Exon Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 8 02:28:53 PST 2016
Author: dexonsmith
Date: Tue Mar 8 04:28:52 2016
New Revision: 262921
URL: http://llvm.org/viewvc/llvm-project?rev=262921&view=rev
Log:
Sema: Methods in unavailable classes are unavailable
Similar to the template cases in r262050, when a C++ method in an
unavailable struct/class calls unavailable API, don't diagnose an error.
I.e., this case was failing:
void foo() __attribute__((unavailable));
struct __attribute__((unavailable)) A {
void bar() { foo(); }
};
Since A is unavailable, A::bar is allowed to call foo. However, we were
emitting a diagnostic here. This commit checks up the context chain
from A::bar, in a manner inspired by SemaDeclAttr.cpp:isDeclUnavailable.
I expected to find other related issues but failed to trigger them:
- I wondered if DeclBase::getAvailability should check for
`TemplateDecl` instead of `FunctionTemplateDecl`, but I couldn't find
a way to trigger this. I left behind a few extra tests to make sure
we don't regress.
- I wondered if Sema::isFunctionConsideredUnavailable should be
symmetric, checking up the context chain of the callee (this commit
only checks up the context chain of the caller). However, I couldn't
think of a testcase that didn't require first referencing the
unavailable type; this, we already diagnose.
rdar://problem/25030656
Modified:
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaCXX/attr-unavailable.cpp
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=262921&r1=262920&r2=262921&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Mar 8 04:28:52 2016
@@ -1150,7 +1150,16 @@ bool Sema::IsOverload(FunctionDecl *New,
/// \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();
+ if (!FD->isUnavailable())
+ return false;
+
+ // Walk up the context of the caller.
+ Decl *C = cast<Decl>(CurContext);
+ do {
+ if (C->isUnavailable())
+ return false;
+ } while ((C = cast_or_null<Decl>(C->getDeclContext())));
+ return true;
}
/// \brief Tries a user-defined conversion from From to ToType.
Modified: cfe/trunk/test/SemaCXX/attr-unavailable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-unavailable.cpp?rev=262921&r1=262920&r2=262921&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-unavailable.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-unavailable.cpp Tue Mar 8 04:28:52 2016
@@ -116,3 +116,26 @@ void calls_unavail_templated() {
void unavail_calls_unavail_templated() __attribute__((unavailable)) {
unavail_templated(5);
}
+
+void unavailable() __attribute((unavailable)); // \
+ expected-note 4{{candidate function has been explicitly made unavailable}}
+struct AvailableStruct {
+ void calls_unavailable() { unavailable(); } // \
+ expected-error{{call to unavailable function 'unavailable'}}
+ template <class U> void calls_unavailable() { unavailable(); } // \
+ expected-error{{call to unavailable function 'unavailable'}}
+};
+template <class T> struct AvailableStructTemplated {
+ void calls_unavailable() { unavailable(); } // \
+ expected-error{{call to unavailable function 'unavailable'}}
+ template <class U> void calls_unavailable() { unavailable(); } // \
+ expected-error{{call to unavailable function 'unavailable'}}
+};
+struct __attribute__((unavailable)) UnavailableStruct {
+ void calls_unavailable() { unavailable(); }
+ template <class U> void calls_unavailable() { unavailable(); }
+};
+template <class T> struct __attribute__((unavailable)) UnavailableStructTemplated {
+ void calls_unavailable() { unavailable(); }
+ template <class U> void calls_unavailable() { unavailable(); }
+};
More information about the cfe-commits
mailing list