[inline-asm]No error for conflict between inputs\outputs and clobber … · llvm/llvm-project@c42fd03 (original) (raw)

`@@ -22,6 +22,7 @@

`

22

22

`#include "clang/Sema/ScopeInfo.h"

`

23

23

`#include "clang/Sema/SemaInternal.h"

`

24

24

`#include "llvm/ADT/ArrayRef.h"

`

``

25

`+

#include "llvm/ADT/StringSet.h"

`

25

26

`#include "llvm/MC/MCParser/MCAsmParser.h"

`

26

27

`using namespace clang;

`

27

28

`using namespace sema;

`

`@@ -137,6 +138,57 @@ static bool checkExprMemoryConstraintCompat(Sema &S, Expr *E,

`

137

138

`return false;

`

138

139

`}

`

139

140

``

``

141

`+

// Extracting the register name from the Expression value,

`

``

142

`+

// if there is no register name to extract, returns ""

`

``

143

`+

static StringRef extractRegisterName(const Expr *Expression,

`

``

144

`+

const TargetInfo &Target) {

`

``

145

`+

Expression = Expression->IgnoreImpCasts();

`

``

146

`+

if (const DeclRefExpr *AsmDeclRef = dyn_cast(Expression)) {

`

``

147

`+

// Handle cases where the expression is a variable

`

``

148

`+

const VarDecl *Variable = dyn_cast(AsmDeclRef->getDecl());

`

``

149

`+

if (Variable && Variable->getStorageClass() == SC_Register) {

`

``

150

`+

if (AsmLabelAttr *Attr = Variable->getAttr())

`

``

151

`+

if (Target.isValidGCCRegisterName(Attr->getLabel()))

`

``

152

`+

return Target.getNormalizedGCCRegisterName(Attr->getLabel(), true);

`

``

153

`+

}

`

``

154

`+

}

`

``

155

`+

return "";

`

``

156

`+

}

`

``

157

+

``

158

`+

// Checks if there is a conflict between the input and output lists with the

`

``

159

`+

// clobbers list. If there's a conflict, returns the location of the

`

``

160

`+

// conflicted clobber, else returns nullptr

`

``

161

`+

static SourceLocation

`

``

162

`+

getClobberConflictLocation(MultiExprArg Exprs, StringLiteral **Constraints,

`

``

163

`+

StringLiteral **Clobbers, int NumClobbers,

`

``

164

`+

const TargetInfo &Target, ASTContext &Cont) {

`

``

165

`+

llvm::StringSet<> InOutVars;

`

``

166

`+

// Collect all the input and output registers from the extended asm

`

``

167

`+

// statement

`

``

168

`+

// in order to check for conflicts with the clobber list

`

``

169

`+

for (int i = 0; i < Exprs.size(); ++i) {

`

``

170

`+

StringRef Constraint = Constraints[i]->getString();

`

``

171

`+

StringRef InOutReg = Target.getConstraintRegister(

`

``

172

`+

Constraint, extractRegisterName(Exprs[i], Target));

`

``

173

`+

if (InOutReg != "")

`

``

174

`+

InOutVars.insert(InOutReg);

`

``

175

`+

}

`

``

176

`+

// Check for each item in the clobber list if it conflicts with the input

`

``

177

`+

// or output

`

``

178

`+

for (int i = 0; i < NumClobbers; ++i) {

`

``

179

`+

StringRef Clobber = Clobbers[i]->getString();

`

``

180

`+

// We only check registers, therefore we don't check cc and memory

`

``

181

`+

// clobbers

`

``

182

`+

if (Clobber == "cc" || Clobber == "memory")

`

``

183

`+

continue;

`

``

184

`+

Clobber = Target.getNormalizedGCCRegisterName(Clobber, true);

`

``

185

`+

// Go over the output's registers we collected

`

``

186

`+

if (InOutVars.count(Clobber))

`

``

187

`+

return Clobbers[i]->getLocStart();

`

``

188

`+

}

`

``

189

`+

return SourceLocation();

`

``

190

`+

}

`

``

191

+

140

192

`StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,

`

141

193

`bool IsVolatile, unsigned NumOutputs,

`

142

194

`unsigned NumInputs, IdentifierInfo **Names,

`

`@@ -543,6 +595,13 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,

`

543

595

`return StmtError();

`

544

596

` }

`

545

597

``

``

598

`+

// Check for conflicts between clobber list and input or output lists

`

``

599

`+

SourceLocation ConstraintLoc =

`

``

600

`+

getClobberConflictLocation(Exprs, Constraints, Clobbers, NumClobbers,

`

``

601

`+

Context.getTargetInfo(), Context);

`

``

602

`+

if (ConstraintLoc.isValid())

`

``

603

`+

return Diag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber);

`

``

604

+

546

605

`return NS;

`

547

606

`}

`

548

607

``