diff options
Diffstat (limited to 'lib/Sema/SemaStmtAsm.cpp')
| -rw-r--r-- | lib/Sema/SemaStmtAsm.cpp | 53 | 
1 files changed, 27 insertions, 26 deletions
| diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index 0d32581e8daa..9f48616ea5bf 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -12,6 +12,7 @@  //===----------------------------------------------------------------------===//  #include "clang/Sema/SemaInternal.h" +#include "clang/AST/ExprCXX.h"  #include "clang/AST/RecordLayout.h"  #include "clang/AST/TypeLoc.h"  #include "clang/Basic/TargetInfo.h" @@ -86,6 +87,11 @@ static bool CheckNakedParmReference(Expr *E, Sema &S) {    WorkList.push_back(E);    while (WorkList.size()) {      Expr *E = WorkList.pop_back_val(); +    if (isa<CXXThisExpr>(E)) { +      S.Diag(E->getLocStart(), diag::err_asm_naked_this_ref); +      S.Diag(Func->getAttr<NakedAttr>()->getLocation(), diag::note_attribute); +      return true; +    }      if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {        if (isa<ParmVarDecl>(DRE->getDecl())) {          S.Diag(DRE->getLocStart(), diag::err_asm_naked_parm_ref); @@ -118,6 +124,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,    // The parser verifies that there is a string literal here.    assert(AsmString->isAscii()); +  bool ValidateConstraints = +      DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl()); +    for (unsigned i = 0; i != NumOutputs; i++) {      StringLiteral *Literal = Constraints[i];      assert(Literal->isAscii()); @@ -127,7 +136,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,        OutputName = Names[i]->getName();      TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName); -    if (!Context.getTargetInfo().validateOutputConstraint(Info)) +    if (ValidateConstraints && +        !Context.getTargetInfo().validateOutputConstraint(Info))        return StmtError(Diag(Literal->getLocStart(),                              diag::err_asm_invalid_output_constraint)                         << Info.getConstraintStr()); @@ -201,8 +211,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,        InputName = Names[i]->getName();      TargetInfo::ConstraintInfo Info(Literal->getString(), InputName); -    if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos.data(), -                                                NumOutputs, Info)) { +    if (ValidateConstraints && +        !Context.getTargetInfo().validateInputConstraint( +            OutputConstraintInfos.data(), NumOutputs, Info)) {        return StmtError(Diag(Literal->getLocStart(),                              diag::err_asm_invalid_input_constraint)                         << Info.getConstraintStr()); @@ -307,32 +318,22 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,      if (!Piece.isOperand()) continue;      // Look for the correct constraint index. -    unsigned Idx = 0; -    unsigned ConstraintIdx = 0; -    for (unsigned i = 0, e = NS->getNumOutputs(); i != e; ++i, ++ConstraintIdx) { -      TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i]; -      if (Idx == Piece.getOperandNo()) -        break; -      ++Idx; - -      if (Info.isReadWrite()) { -        if (Idx == Piece.getOperandNo()) -          break; -        ++Idx; -      } -    } +    unsigned ConstraintIdx = Piece.getOperandNo(); +    unsigned NumOperands = NS->getNumOutputs() + NS->getNumInputs(); -    for (unsigned i = 0, e = NS->getNumInputs(); i != e; ++i, ++ConstraintIdx) { -      TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; -      if (Idx == Piece.getOperandNo()) -        break; -      ++Idx; +    // Look for the (ConstraintIdx - NumOperands + 1)th constraint with +    // modifier '+'. +    if (ConstraintIdx >= NumOperands) { +      unsigned I = 0, E = NS->getNumOutputs(); -      if (Info.isReadWrite()) { -        if (Idx == Piece.getOperandNo()) +      for (unsigned Cnt = ConstraintIdx - NumOperands; I != E; ++I) +        if (OutputConstraintInfos[I].isReadWrite() && Cnt-- == 0) { +          ConstraintIdx = I;            break; -        ++Idx; -      } +        } + +      assert(I != E && "Invalid operand number should have been caught in " +                       " AnalyzeAsmString");      }      // Now that we have the right indexes go ahead and check. | 
