diff options
Diffstat (limited to 'lib/Sema/SemaStmtAsm.cpp')
-rw-r--r-- | lib/Sema/SemaStmtAsm.cpp | 138 |
1 files changed, 78 insertions, 60 deletions
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index 9e084c99d0..8c6012573c 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -1,9 +1,8 @@ //===--- SemaStmtAsm.cpp - Semantic Analysis for Asm Statements -----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -254,15 +253,6 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, // The parser verifies that there is a string literal here. assert(AsmString->isAscii()); - // If we're compiling CUDA file and function attributes indicate that it's not - // for this compilation side, skip all the checks. - if (!DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl())) { - GCCAsmStmt *NS = new (Context) GCCAsmStmt( - Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names, - Constraints, Exprs.data(), AsmString, NumClobbers, Clobbers, RParenLoc); - return NS; - } - for (unsigned i = 0; i != NumOutputs; i++) { StringLiteral *Literal = Constraints[i]; assert(Literal->isAscii()); @@ -272,10 +262,15 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, OutputName = Names[i]->getName(); TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName); - if (!Context.getTargetInfo().validateOutputConstraint(Info)) - return StmtError( - Diag(Literal->getBeginLoc(), diag::err_asm_invalid_output_constraint) - << Info.getConstraintStr()); + if (!Context.getTargetInfo().validateOutputConstraint(Info)) { + targetDiag(Literal->getBeginLoc(), + diag::err_asm_invalid_output_constraint) + << Info.getConstraintStr(); + return new (Context) + GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, + NumInputs, Names, Constraints, Exprs.data(), AsmString, + NumClobbers, Clobbers, RParenLoc); + } ExprResult ER = CheckPlaceholderExpr(Exprs[i]); if (ER.isInvalid()) @@ -329,10 +324,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, unsigned Size = Context.getTypeSize(OutputExpr->getType()); if (!Context.getTargetInfo().validateOutputSize(Literal->getString(), - Size)) - return StmtError( - Diag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size) - << Info.getConstraintStr()); + Size)) { + targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size) + << Info.getConstraintStr(); + return new (Context) + GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, + NumInputs, Names, Constraints, Exprs.data(), AsmString, + NumClobbers, Clobbers, RParenLoc); + } } SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos; @@ -348,9 +347,12 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, TargetInfo::ConstraintInfo Info(Literal->getString(), InputName); if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos, Info)) { - return StmtError( - Diag(Literal->getBeginLoc(), diag::err_asm_invalid_input_constraint) - << Info.getConstraintStr()); + targetDiag(Literal->getBeginLoc(), diag::err_asm_invalid_input_constraint) + << Info.getConstraintStr(); + return new (Context) + GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, + NumInputs, Names, Constraints, Exprs.data(), AsmString, + NumClobbers, Clobbers, RParenLoc); } ExprResult ER = CheckPlaceholderExpr(Exprs[i]); @@ -383,11 +385,20 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, return StmtError( Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected) << Info.getConstraintStr() << InputExpr->getSourceRange()); - llvm::APSInt Result = EVResult.Val.getInt(); - if (!Info.isValidAsmImmediate(Result)) + + // For compatibility with GCC, we also allow pointers that would be + // integral constant expressions if they were cast to int. + llvm::APSInt IntResult; + if (!EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), + Context)) + return StmtError( + Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected) + << Info.getConstraintStr() << InputExpr->getSourceRange()); + + if (!Info.isValidAsmImmediate(IntResult)) return StmtError(Diag(InputExpr->getBeginLoc(), diag::err_invalid_asm_value_for_constraint) - << Result.toString(10) << Info.getConstraintStr() + << IntResult.toString(10) << Info.getConstraintStr() << InputExpr->getSourceRange()); } @@ -422,8 +433,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, unsigned Size = Context.getTypeSize(Ty); if (!Context.getTargetInfo().validateInputSize(Literal->getString(), Size)) - return StmtError( - Diag(InputExpr->getBeginLoc(), diag::err_asm_invalid_input_size) + return StmtResult( + targetDiag(InputExpr->getBeginLoc(), diag::err_asm_invalid_input_size) << Info.getConstraintStr()); } @@ -434,10 +445,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, StringRef Clobber = Literal->getString(); - if (!Context.getTargetInfo().isValidClobber(Clobber)) - return StmtError( - Diag(Literal->getBeginLoc(), diag::err_asm_unknown_register_name) - << Clobber); + if (!Context.getTargetInfo().isValidClobber(Clobber)) { + targetDiag(Literal->getBeginLoc(), diag::err_asm_unknown_register_name) + << Clobber; + return new (Context) + GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, + NumInputs, Names, Constraints, Exprs.data(), AsmString, + NumClobbers, Clobbers, RParenLoc); + } } GCCAsmStmt *NS = @@ -449,9 +464,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, SmallVector<GCCAsmStmt::AsmStringPiece, 8> Pieces; unsigned DiagOffs; if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) { - Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID) - << AsmString->getSourceRange(); - return StmtError(); + targetDiag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID) + << AsmString->getSourceRange(); + return NS; } // Validate constraints and modifiers. @@ -489,16 +504,15 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, if (!Context.getTargetInfo().validateConstraintModifier( Literal->getString(), Piece.getModifier(), Size, SuggestedModifier)) { - Diag(Exprs[ConstraintIdx]->getBeginLoc(), - diag::warn_asm_mismatched_size_modifier); + targetDiag(Exprs[ConstraintIdx]->getBeginLoc(), + diag::warn_asm_mismatched_size_modifier); if (!SuggestedModifier.empty()) { - auto B = Diag(Piece.getRange().getBegin(), - diag::note_asm_missing_constraint_modifier) + auto B = targetDiag(Piece.getRange().getBegin(), + diag::note_asm_missing_constraint_modifier) << SuggestedModifier; SuggestedModifier = "%" + SuggestedModifier + Piece.getString(); - B.AddFixItHint(FixItHint::CreateReplacement(Piece.getRange(), - SuggestedModifier)); + B << FixItHint::CreateReplacement(Piece.getRange(), SuggestedModifier); } } } @@ -509,12 +523,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i]; StringRef ConstraintStr = Info.getConstraintStr(); unsigned AltCount = ConstraintStr.count(',') + 1; - if (NumAlternatives == ~0U) + if (NumAlternatives == ~0U) { NumAlternatives = AltCount; - else if (NumAlternatives != AltCount) - return StmtError(Diag(NS->getOutputExpr(i)->getBeginLoc(), - diag::err_asm_unexpected_constraint_alternatives) - << NumAlternatives << AltCount); + } else if (NumAlternatives != AltCount) { + targetDiag(NS->getOutputExpr(i)->getBeginLoc(), + diag::err_asm_unexpected_constraint_alternatives) + << NumAlternatives << AltCount; + return NS; + } } SmallVector<size_t, 4> InputMatchedToOutput(OutputConstraintInfos.size(), ~0U); @@ -522,12 +538,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; StringRef ConstraintStr = Info.getConstraintStr(); unsigned AltCount = ConstraintStr.count(',') + 1; - if (NumAlternatives == ~0U) + if (NumAlternatives == ~0U) { NumAlternatives = AltCount; - else if (NumAlternatives != AltCount) - return StmtError(Diag(NS->getInputExpr(i)->getBeginLoc(), - diag::err_asm_unexpected_constraint_alternatives) - << NumAlternatives << AltCount); + } else if (NumAlternatives != AltCount) { + targetDiag(NS->getInputExpr(i)->getBeginLoc(), + diag::err_asm_unexpected_constraint_alternatives) + << NumAlternatives << AltCount; + return NS; + } // If this is a tied constraint, verify that the output and input have // either exactly the same type, or that they are int/ptr operands with the @@ -542,13 +560,13 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, // 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)->getBeginLoc(), - diag::err_asm_input_duplicate_match) + targetDiag(NS->getInputExpr(i)->getBeginLoc(), + diag::err_asm_input_duplicate_match) << TiedTo; - Diag(NS->getInputExpr(InputMatchedToOutput[TiedTo])->getBeginLoc(), - diag::note_asm_input_duplicate_first) + targetDiag(NS->getInputExpr(InputMatchedToOutput[TiedTo])->getBeginLoc(), + diag::note_asm_input_duplicate_first) << TiedTo; - return StmtError(); + return NS; } InputMatchedToOutput[TiedTo] = i; @@ -633,10 +651,10 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, continue; } - Diag(InputExpr->getBeginLoc(), diag::err_asm_tying_incompatible_types) + targetDiag(InputExpr->getBeginLoc(), diag::err_asm_tying_incompatible_types) << InTy << OutTy << OutputExpr->getSourceRange() << InputExpr->getSourceRange(); - return StmtError(); + return NS; } // Check for conflicts between clobber list and input or output lists @@ -644,7 +662,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, getClobberConflictLocation(Exprs, Constraints, Clobbers, NumClobbers, Context.getTargetInfo(), Context); if (ConstraintLoc.isValid()) - return Diag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber); + targetDiag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber); return NS; } |