*p; // Now diagnosed as a warning-as-error.
}
+- Clang now diagnoses use of a bit-field as an instruction operand in Microsoft
+ style inline asm blocks as an error. Previously, a bit-field operand yielded
+ the address of the allocation unit the bit-field was stored within; reads or
+ writes therefore had the potential to read or write nearby bit-fields. This
+ change fixes `issue 57791 <https://github.com/llvm/llvm-project/issues/57791>`_.
+
+ .. code-block:: c++
+
+ typedef struct S {
+ unsigned bf:1;
+ } S;
+ void f(S s) {
+ __asm {
+ mov eax, s.bf // Now diagnosed as an error.
+ mov s.bf, eax // Now diagnosed as an error.
+ }
+ }
+
+
What's New in Clang |release|?
==============================
Some of the major new features and improvements to Clang are listed
def err_asm_invalid_type : Error<
"invalid type %0 in asm %select{input|output}1">;
+ def err_ms_asm_bitfield_unsupported : Error<
+ "an inline asm block cannot have an operand which is a bit-field">;
+
def warn_stack_clash_protection_inline_asm : Warning<
"Unable to protect inline asm that clobbers stack pointer against stack clash">,
InGroup<DiagGroup<"stack-protector">>;
bool IsSimple = (NumOutputs != 0 || NumInputs != 0);
setFunctionHasBranchProtectedScope();
+ bool InvalidOperand = false;
for (uint64_t I = 0; I < NumOutputs + NumInputs; ++I) {
- if (Exprs[I]->getType()->isBitIntType())
- return StmtError(
- Diag(Exprs[I]->getBeginLoc(), diag::err_asm_invalid_type)
- << Exprs[I]->getType() << (I < NumOutputs)
- << Exprs[I]->getSourceRange());
+ Expr *E = Exprs[I];
+ if (E->getType()->isBitIntType()) {
+ InvalidOperand = true;
+ Diag(E->getBeginLoc(), diag::err_asm_invalid_type)
+ << E->getType() << (I < NumOutputs)
+ << E->getSourceRange();
+ } else if (E->refersToBitField()) {
+ InvalidOperand = true;
+ FieldDecl *BitField = E->getSourceBitField();
+ Diag(E->getBeginLoc(), diag::err_ms_asm_bitfield_unsupported)
+ << E->getSourceRange();
+ Diag(BitField->getLocation(), diag::note_bitfield_decl);
+ }
}
+ if (InvalidOperand)
+ return StmtError();
MSAsmStmt *NS =
new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,
__asm mov eax, offset A // expected-error {{offset operator cannot yet handle constants}}
}
+// GH57791
+typedef struct S {
+ unsigned bf1:1; // expected-note {{bit-field is declared here}}
+ unsigned bf2:1; // expected-note {{bit-field is declared here}}
+} S;
+void t15(S s) {
+ __asm {
+ mov eax, s.bf1 // expected-error {{an inline asm block cannot have an operand which is a bit-field}}
+ mov s.bf2, eax // expected-error {{an inline asm block cannot have an operand which is a bit-field}}
+ }
+}
+
int t_fail(void) { // expected-note {{to match this}}
__asm
__asm { // expected-error 3 {{expected}} expected-note {{to match this}}