Diagnose malformed x86 inline asm using 'y' constraint.

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
This commit is contained in:
Tim Northover 2013-06-07 00:04:50 +00:00
Родитель 86875b11db
Коммит 1bea653e0d
4 изменённых файлов: 40 добавлений и 5 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
}