diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -3013,7 +3013,7 @@ } IdentifierInfo *getLabelIdentifier(unsigned i) const { - return Names[i + NumInputs]; + return Names[i + NumOutputs + NumInputs]; } AddrLabelExpr *getLabelExpr(unsigned i) const; @@ -3024,11 +3024,11 @@ using labels_const_range = llvm::iterator_range; labels_iterator begin_labels() { - return &Exprs[0] + NumInputs; + return &Exprs[0] + NumOutputs + NumInputs; } labels_iterator end_labels() { - return &Exprs[0] + NumInputs + NumLabels; + return &Exprs[0] + NumOutputs + NumInputs + NumLabels; } labels_range labels() { @@ -3036,11 +3036,11 @@ } const_labels_iterator begin_labels() const { - return &Exprs[0] + NumInputs; + return &Exprs[0] + NumOutputs + NumInputs; } const_labels_iterator end_labels() const { - return &Exprs[0] + NumInputs + NumLabels; + return &Exprs[0] + NumOutputs + NumInputs + NumLabels; } labels_const_range labels() const { diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -456,7 +456,7 @@ } AddrLabelExpr *GCCAsmStmt::getLabelExpr(unsigned i) const { - return cast(Exprs[i + NumInputs]); + return cast(Exprs[i + NumOutputs + NumInputs]); } StringRef GCCAsmStmt::getLabelName(unsigned i) const { @@ -522,7 +522,7 @@ for (unsigned i = 0, e = getNumLabels(); i != e; ++i) if (getLabelName(i) == SymbolicName) - return i + getNumInputs(); + return i + getNumOutputs() + getNumInputs(); // Not found. return -1; diff --git a/clang/lib/Parse/ParseStmtAsm.cpp b/clang/lib/Parse/ParseStmtAsm.cpp --- a/clang/lib/Parse/ParseStmtAsm.cpp +++ b/clang/lib/Parse/ParseStmtAsm.cpp @@ -764,12 +764,6 @@ AteExtraColon = Tok.is(tok::coloncolon); ConsumeToken(); - if (!AteExtraColon && isGotoAsm && Tok.isNot(tok::colon)) { - Diag(Tok, diag::err_asm_goto_cannot_have_output); - SkipUntil(tok::r_paren, StopAtSemi); - return StmtError(); - } - if (!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs)) return StmtError(); } diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -473,10 +473,10 @@ // Look for the correct constraint index. unsigned ConstraintIdx = Piece.getOperandNo(); - // Labels are the last in the Exprs list. - if (NS->isAsmGoto() && ConstraintIdx >= NS->getNumInputs()) - continue; unsigned NumOperands = NS->getNumOutputs() + NS->getNumInputs(); + // Labels are the last in the Exprs list. + if (NS->isAsmGoto() && ConstraintIdx >= NumOperands) + continue; // Look for the (ConstraintIdx - NumOperands + 1)th constraint with // modifier '+'. if (ConstraintIdx >= NumOperands) { diff --git a/clang/test/Parser/asm-goto.c b/clang/test/Parser/asm-goto.c --- a/clang/test/Parser/asm-goto.c +++ b/clang/test/Parser/asm-goto.c @@ -31,14 +31,22 @@ lab: return; } -int zoo () +int +fgoto3 (int x) +{ + __asm__ volatile goto ("decl %0; jnz %l[a]" + : "=r" (x) : "m" (x) : "memory" : a); +a: + return -x; +} + +int +zoo (void) { int x,cond,*e; // expected-error@+1 {{expected ')'}} asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a) - // expected-error@+1 {{'asm goto' cannot have output constraints}} - asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a); - // expected-error@+1 {{expected identifie}} + // expected-error@+1 {{expected identifier}} asm goto ("decl %0;" :: "m"(x) : "memory" : ); // expected-error@+1 {{expected ':'}} asm goto ("decl %0;" :: "m"(x) : "memory" ); diff --git a/clang/test/Parser/asm-goto.cpp b/clang/test/Parser/asm-goto.cpp --- a/clang/test/Parser/asm-goto.cpp +++ b/clang/test/Parser/asm-goto.cpp @@ -6,9 +6,7 @@ int x,cond,*e; // expected-error@+1 {{expected ')'}} asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a) - // expected-error@+1 {{'asm goto' cannot have output constraints}} - asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a); - // expected-error@+1 {{expected identifie}} + // expected-error@+1 {{expected identifier}} asm goto ("decl %0;" :: "m"(x) : "memory" : ); // expected-error@+1 {{expected ':'}} asm goto ("decl %0;" :: "m"(x) : "memory" ); @@ -51,3 +49,12 @@ :: lab); lab: return; } + +int +fgoto3 (int x) +{ + __asm__ volatile goto ("decl %0; jnz %l[a]" + : "=r" (x) : "m" (x) : "memory" : a); +a: + return -x; +}