]> granicus.if.org Git - clang/commitdiff
Diagnose malformed x86 inline asm using 'y' constraint.
authorTim Northover <tnorthover@apple.com>
Fri, 7 Jun 2013 00:04:50 +0000 (00:04 +0000)
committerTim Northover <tnorthover@apple.com>
Fri, 7 Jun 2013 00:04:50 +0000 (00:04 +0000)
X86's 'y' inline assembly constraint represents an MMX register, this change
prevents Clang from hitting an assertion when passed an incompatible type to
deal with.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183467 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGStmt.cpp
lib/CodeGen/TargetInfo.cpp
lib/CodeGen/TargetInfo.h
test/CodeGen/mmx-inline-asm-error.c [new file with mode: 0644]

index 353d6c3d396721bda9aaf1a76c70d763f6e692dc..3e9b8d47ea0c75ab212bcb36b8078a1b4af7de2d 100644 (file)
@@ -16,6 +16,7 @@
 #include "CodeGenModule.h"
 #include "TargetInfo.h"
 #include "clang/AST/StmtVisitor.h"
+#include "clang/Sema/SemaDiagnostic.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/StringExtras.h"
@@ -1559,10 +1560,15 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
           ResultRegTypes.back() = ConvertType(InputTy);
         }
       }
-      if (llvm::Type* AdjTy = 
+      if (llvm::Type* AdjTy =
             getTargetHooks().adjustInlineAsmType(*this, OutputConstraint,
                                                  ResultRegTypes.back()))
         ResultRegTypes.back() = AdjTy;
+      else {
+        CGM.getDiags().Report(S.getAsmLoc(),
+                              diag::err_asm_invalid_type_in_input)
+            << OutExpr->getType() << OutputConstraint;
+      }
     } else {
       ArgTypes.push_back(Dest.getAddress()->getType());
       Args.push_back(Dest.getAddress());
@@ -1578,8 +1584,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
                                             InOutConstraints);
 
       if (llvm::Type* AdjTy =
-            getTargetHooks().adjustInlineAsmType(*this, OutputConstraint,
-                                                 Arg->getType()))
+          getTargetHooks().adjustInlineAsmType(*this, OutputConstraint,
+                                               Arg->getType()))
         Arg = Builder.CreateBitCast(Arg, AdjTy);
 
       if (Info.allowsRegister())
@@ -1644,6 +1650,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
               getTargetHooks().adjustInlineAsmType(*this, InputConstraint,
                                                    Arg->getType()))
       Arg = Builder.CreateBitCast(Arg, AdjTy);
+    else
+      CGM.getDiags().Report(S.getAsmLoc(), diag::err_asm_invalid_type_in_input)
+          << InputExpr->getType() << InputConstraint;
 
     ArgTypes.push_back(Arg->getType());
     Args.push_back(Arg);
index c4ee7246a5be387e77dcc0e4fb1f3a788126a106..6881ea7fec066e16066584895a47eeb865fd3582 100644 (file)
@@ -503,8 +503,16 @@ bool IsX86_MMXType(llvm::Type *IRType) {
 static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF,
                                           StringRef Constraint,
                                           llvm::Type* Ty) {
-  if ((Constraint == "y" || Constraint == "&y") && Ty->isVectorTy())
+  if ((Constraint == "y" || Constraint == "&y") && Ty->isVectorTy()) {
+    if (cast<llvm::VectorType>(Ty)->getBitWidth() != 64) {
+      // Invalid MMX constraint
+      return 0;
+    }
+
     return llvm::Type::getX86_MMXTy(CGF.getLLVMContext());
+  }
+
+  // No operation needed
   return Ty;
 }
 
index b0ddebc1a0383cc79b8ed76a0cfb092f62a7b682..ab7b061aba8454b408b6932896b3265e831ffb7a 100644 (file)
@@ -111,8 +111,13 @@ namespace clang {
       return Address;
     }
 
+    /// Corrects the low-level LLVM type for a given constraint and "usual"
+    /// type.
+    ///
+    /// \returns A pointer to a new LLVM type, possibly the same as the original
+    /// on success; 0 on failure.
     virtual llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF,
-                                            StringRef Constraint, 
+                                            StringRef Constraint,
                                             llvm::Type* Ty) const {
       return Ty;
     }
diff --git a/test/CodeGen/mmx-inline-asm-error.c b/test/CodeGen/mmx-inline-asm-error.c
new file mode 100644 (file)
index 0000000..a639368
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -verify -triple x86_64-unknown-unknown -emit-llvm-only %s
+typedef int vec256 __attribute__((ext_vector_type(8)));
+
+vec256 foo(vec256 in) {
+  vec256 out;
+
+  asm("something %0" : : "y"(in)); // expected-error {{invalid type 'vec256' in asm input for constraint 'y'}}
+  asm("something %0" : "=y"(out)); // expected-error {{invalid type 'vec256' in asm input for constraint 'y'}}
+  asm("something %0, %0" : "+y"(out)); // expected-error {{invalid type 'vec256' in asm input for constraint 'y'}}
+
+  return out;
+}
+