r301532 - [ObjC] Disallow vector parameters and return values in Objective-C methods
Alex Lorenz via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 27 03:43:48 PDT 2017
Author: arphaman
Date: Thu Apr 27 05:43:48 2017
New Revision: 301532
URL: http://llvm.org/viewvc/llvm-project?rev=301532&view=rev
Log:
[ObjC] Disallow vector parameters and return values in Objective-C methods
for iOS < 9 and OS X < 10.11 X86 targets
This commit adds a new error that disallows methods that have parameters/return
values with a vector type for some older X86 targets. This diagnostic is
needed because objc_msgSend doesn't support SIMD vector registers/return values
on X86 in iOS < 9 and OS X < 10.11. Note that we don't necessarily know if the
vector argument/return value will use a SIMD register, so instead we chose to
be conservative and prohibit all vector types.
rdar://21662309
Differential Revision: https://reviews.llvm.org/D28670
Added:
cfe/trunk/test/SemaObjC/x86-method-vector-values.m
Modified:
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=301532&r1=301531&r2=301532&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Thu Apr 27 05:43:48 2017
@@ -616,6 +616,14 @@ public:
getAvailability(std::string *Message = nullptr,
VersionTuple EnclosingVersion = VersionTuple()) const;
+ /// \brief Retrieve the version of the target platform in which this
+ /// declaration was introduced.
+ ///
+ /// \returns An empty version tuple if this declaration has no 'introduced'
+ /// availability attributes, or the version tuple that's specified in the
+ /// attribute otherwise.
+ VersionTuple getVersionIntroduced() const;
+
/// \brief Determine whether this declaration is marked 'deprecated'.
///
/// \param Message If non-NULL and the declaration is deprecated,
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=301532&r1=301531&r2=301532&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Apr 27 05:43:48 2017
@@ -1180,6 +1180,10 @@ def err_objc_kindof_nonobject : Error<
def err_objc_kindof_wrong_position : Error<
"'__kindof' type specifier must precede the declarator">;
+def err_objc_method_unsupported_param_ret_type : Error<
+ "%0 %select{parameter|return}1 type is unsupported; "
+ "support for vector types for this target is introduced in %2">;
+
// C++ declarations
def err_static_assert_expression_is_not_constant : Error<
"static_assert expression is not an integral constant expression">;
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=301532&r1=301531&r2=301532&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Thu Apr 27 05:43:48 2017
@@ -415,6 +415,19 @@ const Attr *Decl::getDefiningAttr() cons
return nullptr;
}
+StringRef getRealizedPlatform(const AvailabilityAttr *A,
+ const ASTContext &Context) {
+ // Check if this is an App Extension "platform", and if so chop off
+ // the suffix for matching with the actual platform.
+ StringRef RealizedPlatform = A->getPlatform()->getName();
+ if (!Context.getLangOpts().AppExt)
+ return RealizedPlatform;
+ size_t suffix = RealizedPlatform.rfind("_app_extension");
+ if (suffix != StringRef::npos)
+ return RealizedPlatform.slice(0, suffix);
+ return RealizedPlatform;
+}
+
/// \brief Determine the availability of the given declaration based on
/// the target platform.
///
@@ -434,20 +447,11 @@ static AvailabilityResult CheckAvailabil
if (EnclosingVersion.empty())
return AR_Available;
- // Check if this is an App Extension "platform", and if so chop off
- // the suffix for matching with the actual platform.
StringRef ActualPlatform = A->getPlatform()->getName();
- StringRef RealizedPlatform = ActualPlatform;
- if (Context.getLangOpts().AppExt) {
- size_t suffix = RealizedPlatform.rfind("_app_extension");
- if (suffix != StringRef::npos)
- RealizedPlatform = RealizedPlatform.slice(0, suffix);
- }
-
StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
// Match the platform name.
- if (RealizedPlatform != TargetPlatform)
+ if (getRealizedPlatform(A, Context) != TargetPlatform)
return AR_Available;
StringRef PrettyPlatformName
@@ -567,6 +571,20 @@ AvailabilityResult Decl::getAvailability
return Result;
}
+VersionTuple Decl::getVersionIntroduced() const {
+ const ASTContext &Context = getASTContext();
+ StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
+ for (const auto *A : attrs()) {
+ if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
+ if (getRealizedPlatform(Availability, Context) != TargetPlatform)
+ continue;
+ if (!Availability->getIntroduced().empty())
+ return Availability->getIntroduced();
+ }
+ }
+ return VersionTuple();
+}
+
bool Decl::canBeWeakImported(bool &IsDefinition) const {
IsDefinition = false;
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=301532&r1=301531&r2=301532&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Apr 27 05:43:48 2017
@@ -4313,6 +4313,51 @@ static void mergeInterfaceMethodToImpl(S
}
}
+/// Verify that the method parameters/return value have types that are supported
+/// by the x86 target.
+static void checkObjCMethodX86VectorTypes(Sema &SemaRef,
+ const ObjCMethodDecl *Method) {
+ assert(SemaRef.getASTContext().getTargetInfo().getTriple().getArch() ==
+ llvm::Triple::x86 &&
+ "x86-specific check invoked for a different target");
+ SourceLocation Loc;
+ QualType T;
+ for (const ParmVarDecl *P : Method->parameters()) {
+ if (P->getType()->isVectorType()) {
+ Loc = P->getLocStart();
+ T = P->getType();
+ break;
+ }
+ }
+ if (Loc.isInvalid()) {
+ if (Method->getReturnType()->isVectorType()) {
+ Loc = Method->getReturnTypeSourceRange().getBegin();
+ T = Method->getReturnType();
+ } else
+ return;
+ }
+
+ // Vector parameters/return values are not supported by objc_msgSend on x86 in
+ // iOS < 9 and macOS < 10.11.
+ const auto &Triple = SemaRef.getASTContext().getTargetInfo().getTriple();
+ VersionTuple AcceptedInVersion;
+ if (Triple.getOS() == llvm::Triple::IOS)
+ AcceptedInVersion = VersionTuple(/*Major=*/9);
+ else if (Triple.isMacOSX())
+ AcceptedInVersion = VersionTuple(/*Major=*/10, /*Minor=*/11);
+ else
+ return;
+ VersionTuple MethodVersion = Method->getVersionIntroduced();
+ if (SemaRef.getASTContext().getTargetInfo().getPlatformMinVersion() >=
+ AcceptedInVersion &&
+ (MethodVersion.empty() || MethodVersion >= AcceptedInVersion))
+ return;
+ SemaRef.Diag(Loc, diag::err_objc_method_unsupported_param_ret_type)
+ << T << (Method->getReturnType()->isVectorType() ? /*return value*/ 1
+ : /*parameter*/ 0)
+ << (Triple.isMacOSX() ? "macOS 10.11" : "iOS 9");
+}
+
Decl *Sema::ActOnMethodDeclaration(
Scope *S,
SourceLocation MethodLoc, SourceLocation EndLoc,
@@ -4534,6 +4579,10 @@ Decl *Sema::ActOnMethodDeclaration(
ObjCMethod->SetRelatedResultType();
}
+ if (MethodDefinition &&
+ Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
+ checkObjCMethodX86VectorTypes(*this, ObjCMethod);
+
ActOnDocumentableDecl(ObjCMethod);
return ObjCMethod;
Added: cfe/trunk/test/SemaObjC/x86-method-vector-values.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/x86-method-vector-values.m?rev=301532&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/x86-method-vector-values.m (added)
+++ cfe/trunk/test/SemaObjC/x86-method-vector-values.m Thu Apr 27 05:43:48 2017
@@ -0,0 +1,132 @@
+// RUN: %clang_cc1 -verify -DMAC -triple=i686-apple-macosx10.10 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DMAC -triple=i686-apple-macosx10.4 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DMAC -triple=i686-apple-darwin14 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -triple=i686-apple-ios8 -Wno-objc-root-class %s
+
+// RUN: %clang_cc1 -verify -DALLOW -DMAC -triple=i686-apple-macosx10.11 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DALLOW -DMAC -triple=i686-apple-darwin15 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DALLOW -DIOS -triple=i686-apple-ios9 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DALLOW -DOTHER -triple=i686-apple-watchos -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DALLOW -DOTHER -triple=i686-apple-tvos -Wno-objc-root-class %s
+
+// RUN: %clang_cc1 -verify -DALLOW -DOTHER -triple=x86_64-apple-macosx10.10 -Wno-objc-root-class %s
+
+// rdar://21662309
+
+typedef __attribute__((__ext_vector_type__(3))) float float3;
+
+typedef float __m128 __attribute__((__vector_size__(16)));
+
+struct Aggregate { __m128 v; };
+struct AggregateFloat { float v; };
+
+#define AVAILABLE_MACOS_10_10 __attribute__((availability(macos, introduced = 10.10)))
+#define AVAILABLE_MACOS_10_11 __attribute__((availability(macos, introduced = 10.11)))
+
+#define AVAILABLE_IOS_8 __attribute__((availability(ios, introduced = 8.0)))
+#define AVAILABLE_IOS_9 __attribute__((availability(ios, introduced = 9.0)))
+
+ at interface VectorMethods
+
+-(void)takeVector:(float3)v; // there should be no diagnostic at declaration
+-(void)takeM128:(__m128)v;
+
+ at end
+
+ at implementation VectorMethods
+
+#ifndef ALLOW
+
+-(void)takeVector:(float3)v {
+#ifdef MAC
+ // expected-error at -2 {{'float3' (vector of 3 'float' values) parameter type is unsupported; support for vector types for this target is introduced in macOS 10.11}}
+#else
+ // expected-error at -4 {{'float3' (vector of 3 'float' values) parameter type is unsupported; support for vector types for this target is introduced in iOS 9}}
+#endif
+}
+
+-(float3)retVector { // expected-error {{'float3' (vector of 3 'float' values) return type is unsupported}}
+}
+
+-(void)takeVector2:(float3)v AVAILABLE_MACOS_10_10 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}}
+}
+
+-(void)takeVector3:(float3)v AVAILABLE_MACOS_10_11 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}}
+}
+
+-(void)takeVector4:(float3)v AVAILABLE_IOS_8 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}}
+}
+
+-(void)takeVector5:(float3)v AVAILABLE_IOS_9 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}}
+}
+
+- (__m128)retM128 { // expected-error {{'__m128' (vector of 4 'float' values) return type is unsupported}}
+}
+
+- (void)takeM128:(__m128)v { // expected-error {{'__m128' (vector of 4 'float' values) parameter type is unsupported}}
+}
+
+#else
+
+-(void)takeVector:(float3)v {
+}
+
+-(float3)retVector {
+ return 0;
+}
+
+- (__m128)retM128 {
+ __m128 value;
+ return value;
+}
+
+- (void)takeM128:(__m128)v {
+}
+
+-(void)takeVector2:(float3)v AVAILABLE_MACOS_10_10 {
+#ifdef MAC
+// expected-error at -2 {{'float3' (vector of 3 'float' values) parameter type is unsupported}}
+#endif
+}
+
+- (__m128)retM128_2 AVAILABLE_MACOS_10_10 {
+#ifdef MAC
+// expected-error at -2 {{'__m128' (vector of 4 'float' values) return type is unsupported}}
+#endif
+ __m128 value;
+ return value;
+}
+
+-(void)takeVector3:(float3)v AVAILABLE_MACOS_10_11 { // no error
+}
+
+-(void)takeVector4:(float3)v AVAILABLE_IOS_8 {
+#ifdef IOS
+ // expected-error at -2 {{'float3' (vector of 3 'float' values) parameter type is unsupported}}
+#endif
+}
+
+-(void)takeVector5:(float3)v AVAILABLE_IOS_9 { // no error
+}
+
+#ifdef OTHER
+// expected-no-diagnostics
+#endif
+
+#endif
+
+-(void)doStuff:(int)m { // no error
+}
+
+-(struct Aggregate)takesAndRetVectorInAggregate:(struct Aggregate)f { // no error
+ struct Aggregate result;
+ return result;
+}
+
+-(struct AggregateFloat)takesAndRetFloatInAggregate:(struct AggregateFloat)f { // no error
+ struct AggregateFloat result;
+ return result;
+}
+
+
+ at end
More information about the cfe-commits
mailing list