forked from OSchip/llvm-project
Fix for PR14269: Clang crashes when a bit field is used as inline assembler
input / output with memory constraint. One generally can't get address of a bit field, so the general solution is to error on such cases. GCC does the same. Patch by Andrey Bokhanko Differential Revision: http://reviews.llvm.org/D10086 llvm-svn: 239153
This commit is contained in:
parent
5a589ad603
commit
eae29e247e
|
@ -6338,6 +6338,9 @@ let CategoryName = "Inline Assembly Issue" in {
|
|||
"remove the cast or build with -fheinous-gnu-extensions">;
|
||||
def err_invalid_asm_value_for_constraint
|
||||
: Error <"value '%0' out of range for constraint '%1'">;
|
||||
def err_asm_bitfield_in_memory_constraint
|
||||
: Error <"reference to a bit-field in asm "
|
||||
"%select{input|output}0 with a memory constraint '%1'">;
|
||||
|
||||
def warn_asm_label_on_auto_decl : Warning<
|
||||
"ignored asm label '%0' on automatic variable">;
|
||||
|
|
|
@ -154,6 +154,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|||
if (CheckNakedParmReference(OutputExpr, *this))
|
||||
return StmtError();
|
||||
|
||||
// Bitfield can't be referenced with a pointer.
|
||||
if (Info.allowsMemory() && OutputExpr->refersToBitField())
|
||||
return StmtError(Diag(OutputExpr->getLocStart(),
|
||||
diag::err_asm_bitfield_in_memory_constraint)
|
||||
<< 1
|
||||
<< Info.getConstraintStr()
|
||||
<< OutputExpr->getSourceRange());
|
||||
|
||||
OutputConstraintInfos.push_back(Info);
|
||||
|
||||
// If this is dependent, just continue.
|
||||
|
@ -230,6 +238,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|||
if (CheckNakedParmReference(InputExpr, *this))
|
||||
return StmtError();
|
||||
|
||||
// Bitfield can't be referenced with a pointer.
|
||||
if (Info.allowsMemory() && InputExpr->refersToBitField())
|
||||
return StmtError(Diag(InputExpr->getLocStart(),
|
||||
diag::err_asm_bitfield_in_memory_constraint)
|
||||
<< 0
|
||||
<< Info.getConstraintStr()
|
||||
<< InputExpr->getSourceRange());
|
||||
|
||||
// Only allow void types for memory constraints.
|
||||
if (Info.allowsMemory() && !Info.allowsRegister()) {
|
||||
if (CheckAsmLValue(InputExpr, *this))
|
||||
|
|
|
@ -204,3 +204,20 @@ void fn6() {
|
|||
: "=rm"(a), "=rm"(a)
|
||||
: "11m"(a)) // expected-error {{invalid input constraint '11m' in asm}}
|
||||
}
|
||||
|
||||
// PR14269
|
||||
typedef struct test16_foo {
|
||||
unsigned int field1 : 1;
|
||||
unsigned int field2 : 2;
|
||||
unsigned int field3 : 3;
|
||||
} test16_foo;
|
||||
test16_foo x;
|
||||
void test16()
|
||||
{
|
||||
__asm__("movl $5, %0"
|
||||
: "=rm" (x.field2)); // expected-error {{reference to a bit-field in asm output with a memory constraint '=rm'}}
|
||||
__asm__("movl $5, %0"
|
||||
:
|
||||
: "m" (x.field3)); // expected-error {{reference to a bit-field in asm input with a memory constraint 'm'}}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue