Skip to content

Commit

Permalink
Fix for PR14269: Clang crashes when a bit field is used as inline ass…
Browse files Browse the repository at this point in the history
…embler

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
  • Loading branch information
amusman committed Jun 5, 2015
1 parent 5a589ad commit eae29e2
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Expand Up @@ -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">;
Expand Down
16 changes: 16 additions & 0 deletions clang/lib/Sema/SemaStmtAsm.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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))
Expand Down
17 changes: 17 additions & 0 deletions clang/test/Sema/asm.c
Expand Up @@ -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'}}
}

0 comments on commit eae29e2

Please sign in to comment.