summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaStmtAsm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaStmtAsm.cpp')
-rw-r--r--lib/Sema/SemaStmtAsm.cpp53
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.