From: Alexander Musman Date: Mon, 21 Sep 2015 14:41:00 +0000 (+0000) Subject: Fix assertion in inline assembler IR gen X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=01841ea1ce9afda895f26dcdb2f74994f52ed35c;p=clang Fix assertion in inline assembler IR gen Several inputs may not refer to one output constraint in inline assembler insertions, clang was failing on assertion on such test case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@248158 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 3432b6c268..67e629f29e 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -6418,6 +6418,8 @@ let CategoryName = "Inline Assembly Issue" in { def err_asm_non_addr_value_in_memory_constraint : Error < "reference to a %select{bit-field|vector element|global register variable}0" " in asm %select{input|output}1 with a memory constraint '%2'">; + def err_asm_input_duplicate_match : Error< + "more than one input constraint matches the same output '%0'">; def warn_asm_label_on_auto_decl : Warning< "ignored asm label '%0' on automatic variable">; @@ -6432,6 +6434,8 @@ let CategoryName = "Inline Assembly Issue" in { def note_asm_missing_constraint_modifier : Note< "use constraint modifier \"%0\"">; + def note_asm_input_duplicate_first : Note< + "constraint '%0' is already present here">; } let CategoryName = "Semantic Issue" in { diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index b148cc9c76..79c06367e0 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -420,6 +420,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, diag::err_asm_unexpected_constraint_alternatives) << NumAlternatives << AltCount); } + SmallVector InputMatchedToOutput(OutputConstraintInfos.size(), + ~0U); for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) { TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; StringRef ConstraintStr = Info.getConstraintStr(); @@ -441,6 +443,19 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, Expr *OutputExpr = Exprs[TiedTo]; Expr *InputExpr = Exprs[InputOpNo]; + // Make sure no more than one input constraint matches each output. + assert(TiedTo < InputMatchedToOutput.size() && "TiedTo value out of range"); + if (InputMatchedToOutput[TiedTo] != ~0U) { + Diag(NS->getInputExpr(i)->getLocStart(), + diag::err_asm_input_duplicate_match) + << TiedTo; + Diag(NS->getInputExpr(InputMatchedToOutput[TiedTo])->getLocStart(), + diag::note_asm_input_duplicate_first) + << TiedTo; + return StmtError(); + } + InputMatchedToOutput[TiedTo] = i; + if (OutputExpr->isTypeDependent() || InputExpr->isTypeDependent()) continue; diff --git a/test/Sema/asm.c b/test/Sema/asm.c index 9ed8d843ea..76e20158c4 100644 --- a/test/Sema/asm.c +++ b/test/Sema/asm.c @@ -236,3 +236,15 @@ void test16() : "m" (test16_baz)); // expected-error {{reference to a global register variable in asm output with a memory constraint 'm'}} } +int test17(int t0) +{ + int r0, r1; + __asm ("addl %2, %2\n\t" + "movl $123, %0" + : "=a" (r0), + "=&r" (r1) + : "1" (t0), // expected-note {{constraint '1' is already present here}} + "1" (t0)); // expected-error {{more than one input constraint matches the same output '1'}} + return r0 + r1; +} +