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