Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -6334,6 +6334,9 @@ "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">; Index: lib/Sema/SemaStmtAsm.cpp =================================================================== --- lib/Sema/SemaStmtAsm.cpp +++ lib/Sema/SemaStmtAsm.cpp @@ -154,6 +154,14 @@ if (CheckNakedParmReference(OutputExpr, *this)) return StmtError(); + // Bit field 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 @@ if (CheckNakedParmReference(InputExpr, *this)) return StmtError(); + // Bit field 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)) Index: test/Sema/asm.c =================================================================== --- test/Sema/asm.c +++ test/Sema/asm.c @@ -204,3 +204,20 @@ : "=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'}} +} +