aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2012-11-12 06:42:51 +0000
committerBill Wendling <isanbard@gmail.com>2012-11-12 06:42:51 +0000
commit68fd608c2c0866064e974c3d43778c47c1cbb080 (patch)
treee2c7183de084260133fe95211e56ba2a548e1c9a
parentc6b82c353bef4cbc0d1dde8580abf8d0a266e64b (diff)
Check that the input size is correct for the given constraint.
The 'a', 'c', and 'd' constraints on i386 mean a 32-bit register. We cannot place a 64-bit value into the 32-bit register. Error out instead of causing the compiler to spew general badness. <rdar://problem/12415959> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167717 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--include/clang/Basic/TargetInfo.h4
-rw-r--r--lib/Basic/Targets.cpp13
-rw-r--r--lib/Sema/SemaStmtAsm.cpp11
-rw-r--r--test/CodeGen/x86_32-inline-asm.c18
5 files changed, 48 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 0d64bf38ad..9110fa36fd 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5141,6 +5141,8 @@ let CategoryName = "Inline Assembly Issue" in {
"%diff{$ matching output with type $|}0,1">;
def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
def err_asm_empty : Error<"__asm used with no assembly instructions">;
+ def err_asm_invalid_input_size : Error<
+ "invalid input size for constraint '%0'">;
def err_invalid_asm_cast_lvalue : Error<
"invalid use of a cast in a inline asm context requiring an l-value: "
"remove the cast or build with -fheinous-gnu-extensions">;
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index b0e58050d5..6774e8ed2c 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -517,6 +517,10 @@ public:
bool validateInputConstraint(ConstraintInfo *OutputConstraints,
unsigned NumOutputs,
ConstraintInfo &info) const;
+ virtual bool validateInputSize(StringRef /*Constraint*/,
+ unsigned /*Size*/) const {
+ return true;
+ }
virtual bool validateConstraintModifier(StringRef /*Constraint*/,
const char /*Modifier*/,
unsigned /*Size*/) const {
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 26a4f41442..ea4ac27a35 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -2595,6 +2595,19 @@ public:
if (RegNo == 1) return 2;
return -1;
}
+ virtual bool validateInputSize(StringRef Constraint,
+ unsigned Size) const {
+ switch (Constraint[0]) {
+ default: break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ return Size == 32;
+ }
+
+ return true;
+ }
};
} // end anonymous namespace
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index 7c2c766e46..e3b5dd851f 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -179,6 +179,17 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
Exprs[i] = Result.take();
InputConstraintInfos.push_back(Info);
+
+ const Type *Ty = Exprs[i]->getType().getTypePtr();
+ if (Ty->isDependentType() || Ty->isIncompleteType())
+ continue;
+
+ unsigned Size = Context.getTypeSize(Ty);
+ if (!Context.getTargetInfo().validateInputSize(Literal->getString(),
+ Size))
+ return StmtError(Diag(InputExpr->getLocStart(),
+ diag::err_asm_invalid_input_size)
+ << Info.getConstraintStr());
}
// Check that the clobbers are valid.
diff --git a/test/CodeGen/x86_32-inline-asm.c b/test/CodeGen/x86_32-inline-asm.c
new file mode 100644
index 0000000000..0596ba4307
--- /dev/null
+++ b/test/CodeGen/x86_32-inline-asm.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -verify %s
+// <rdar://problem/12415959>
+
+typedef unsigned int u_int32_t;
+typedef u_int32_t uint32_t;
+
+typedef unsigned long long u_int64_t;
+typedef u_int64_t uint64_t;
+
+int main () {
+ uint32_t msr = 0x8b;
+ uint64_t val = 0;
+ __asm__ volatile("wrmsr"
+ :
+ : "c" (msr),
+ "a" ((val & 0xFFFFFFFFUL)), // expected-error {{invalid input size for constraint 'a'}}
+ "d" (((val >> 32) & 0xFFFFFFFFUL)));
+}