[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 12 11:22:21 PDT 2025
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff 90a08fb4b7e79e79121a563ac9cd8138cfedeb3c 84508166a9784701dad659881bf75f9764e53f54 --extensions cpp,h -- clang/include/clang/AST/Expr.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/Stmt.h clang/include/clang/Sema/Sema.h clang/lib/AST/ASTImporter.cpp clang/lib/AST/ExprConstant.cpp clang/lib/AST/Stmt.cpp clang/lib/AST/StmtPrinter.cpp clang/lib/AST/StmtProfile.cpp clang/lib/CodeGen/CGStmt.cpp clang/lib/Parse/ParseStmtAsm.cpp clang/lib/Parse/Parser.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaStmtAsm.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp
``````````
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 7f9e50dfe7..28437b5629 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -787,10 +787,9 @@ public:
const Expr *PtrExpression, ASTContext &Ctx,
EvalResult &Status) const;
- bool EvaluateCharRangeAsString(APValue &Result,
- const Expr *SizeExpression,
- const Expr *PtrExpression, ASTContext &Ctx,
- EvalResult &Status) const;
+ bool EvaluateCharRangeAsString(APValue &Result, const Expr *SizeExpression,
+ const Expr *PtrExpression, ASTContext &Ctx,
+ EvalResult &Status) const;
/// If the current Expr can be evaluated to a pointer to a null-terminated
/// constant string, return the constant string (without the terminating
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 7bf0a6911c..88ae3aeefa 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -3314,9 +3314,8 @@ public:
GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
bool isvolatile, unsigned numoutputs, unsigned numinputs,
IdentifierInfo **names, Expr **constraints, Expr **exprs,
- Expr *asmstr, unsigned numclobbers,
- Expr **clobbers, unsigned numlabels,
- SourceLocation rparenloc);
+ Expr *asmstr, unsigned numclobbers, Expr **clobbers,
+ unsigned numlabels, SourceLocation rparenloc);
/// Build an empty inline-assembly statement.
explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {}
@@ -3404,9 +3403,7 @@ public:
const Expr *getOutputConstraintExpr(unsigned i) const {
return Constraints[i];
}
- Expr *getOutputConstraintExpr(unsigned i) {
- return Constraints[i];
- }
+ Expr *getOutputConstraintExpr(unsigned i) { return Constraints[i]; }
Expr *getOutputExpr(unsigned i);
@@ -3443,7 +3440,7 @@ public:
return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
}
- static std::string ExtractStringFromGCCAsmStmtComponent(const Expr* E);
+ static std::string ExtractStringFromGCCAsmStmtComponent(const Expr *E);
//===--- Labels ---===//
@@ -3493,12 +3490,9 @@ public:
private:
void setOutputsAndInputsAndClobbers(const ASTContext &C,
IdentifierInfo **Names,
- Expr **Constraints,
- Stmt **Exprs,
- unsigned NumOutputs,
- unsigned NumInputs,
- unsigned NumLabels,
- Expr **Clobbers,
+ Expr **Constraints, Stmt **Exprs,
+ unsigned NumOutputs, unsigned NumInputs,
+ unsigned NumLabels, Expr **Clobbers,
unsigned NumClobbers);
public:
@@ -3512,9 +3506,7 @@ public:
std::string getClobber(unsigned i) const;
Expr *getClobberExpr(unsigned i) { return Clobbers[i]; }
- const Expr *getClobberExpr(unsigned i) const {
- return Clobbers[i];
- }
+ const Expr *getClobberExpr(unsigned i) const { return Clobbers[i]; }
SourceLocation getBeginLoc() const LLVM_READONLY { return AsmLoc; }
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e1b1083675..4043699912 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5585,10 +5585,7 @@ public:
void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
void ActOnFinishDelayedMemberInitializers(Decl *Record);
- enum class StringEvaluationContext {
- StaticAssert = 0,
- Asm = 1
- };
+ enum class StringEvaluationContext { StaticAssert = 0, Asm = 1 };
bool EvaluateAsString(Expr *Message, APValue &Result, ASTContext &Ctx,
StringEvaluationContext EvalContext,
@@ -11049,7 +11046,7 @@ private:
///@{
public:
- ExprResult ActOnGCCAsmStmtString(Expr* Stm, bool ForAsmLabel);
+ ExprResult ActOnGCCAsmStmtString(Expr *Stm, bool ForAsmLabel);
StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
bool IsVolatile, unsigned NumOutputs,
unsigned NumInputs, IdentifierInfo **Names,
@@ -15339,14 +15336,12 @@ void Sema::PragmaStack<Sema::AlignPackInfo>::Act(SourceLocation PragmaLocation,
llvm::StringRef StackSlotLabel,
AlignPackInfo Value);
-inline
-const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
- Sema::StringEvaluationContext Ctx) {
+inline const StreamingDiagnostic &
+operator<<(const StreamingDiagnostic &DB, Sema::StringEvaluationContext Ctx) {
DB << llvm::to_underlying(Ctx);
return DB;
}
-
} // end namespace clang
#endif
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 86fe8554cb..70f3531524 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -17929,69 +17929,70 @@ std::optional<std::string> Expr::tryEvaluateString(ASTContext &Ctx) const {
}
template <typename T>
-static bool EvaluateCharRangeAsStringImpl(const Expr*, T& Result,
+static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result,
const Expr *SizeExpression,
- const Expr *PtrExpression, ASTContext &Ctx,
+ const Expr *PtrExpression,
+ ASTContext &Ctx,
Expr::EvalResult &Status) {
- LValue String;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
- Info.InConstantContext = true;
-
- FullExpressionRAII Scope(Info);
- APSInt SizeValue;
- if (!::EvaluateInteger(SizeExpression, SizeValue, Info))
- return false;
+ LValue String;
+ EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
+ Info.InConstantContext = true;
- uint64_t Size = SizeValue.getZExtValue();
+ FullExpressionRAII Scope(Info);
+ APSInt SizeValue;
+ if (!::EvaluateInteger(SizeExpression, SizeValue, Info))
+ return false;
- if constexpr(std::is_same_v<APValue, T>)
- Result = APValue(APValue::UninitArray{}, Size, Size);
- //else
- // Result.reserve(Size);
+ uint64_t Size = SizeValue.getZExtValue();
- if (!::EvaluatePointer(PtrExpression, String, Info))
- return false;
+ if constexpr (std::is_same_v<APValue, T>)
+ Result = APValue(APValue::UninitArray{}, Size, Size);
+ // else
+ // Result.reserve(Size);
- QualType CharTy = PtrExpression->getType()->getPointeeType();
- for (uint64_t I = 0; I < Size; ++I) {
- APValue Char;
- if (!handleLValueToRValueConversion(Info, PtrExpression, CharTy, String,
- Char))
- return false;
+ if (!::EvaluatePointer(PtrExpression, String, Info))
+ return false;
- if constexpr(std::is_same_v<APValue, T>) {
- Result.getArrayInitializedElt(I) = std::move(Char);
- }
- else {
- APSInt C = Char.getInt();
- Result.push_back(static_cast<char>(C.getExtValue()));
- }
+ QualType CharTy = PtrExpression->getType()->getPointeeType();
+ for (uint64_t I = 0; I < Size; ++I) {
+ APValue Char;
+ if (!handleLValueToRValueConversion(Info, PtrExpression, CharTy, String,
+ Char))
+ return false;
- if (!HandleLValueArrayAdjustment(Info, PtrExpression, String, CharTy, 1))
- return false;
+ if constexpr (std::is_same_v<APValue, T>) {
+ Result.getArrayInitializedElt(I) = std::move(Char);
+ } else {
+ APSInt C = Char.getInt();
+ Result.push_back(static_cast<char>(C.getExtValue()));
}
- if (!Scope.destroy())
- return false;
- if (!CheckMemoryLeaks(Info))
+ if (!HandleLValueArrayAdjustment(Info, PtrExpression, String, CharTy, 1))
return false;
+ }
+ if (!Scope.destroy())
+ return false;
- return true;
-}
+ if (!CheckMemoryLeaks(Info))
+ return false;
+ return true;
+}
bool Expr::EvaluateCharRangeAsString(std::string &Result,
const Expr *SizeExpression,
const Expr *PtrExpression, ASTContext &Ctx,
EvalResult &Status) const {
- return EvaluateCharRangeAsStringImpl(this, Result, SizeExpression, PtrExpression, Ctx, Status);
+ return EvaluateCharRangeAsStringImpl(this, Result, SizeExpression,
+ PtrExpression, Ctx, Status);
}
bool Expr::EvaluateCharRangeAsString(APValue &Result,
- const Expr *SizeExpression,
- const Expr *PtrExpression, ASTContext &Ctx,
- EvalResult &Status) const {
- return EvaluateCharRangeAsStringImpl(this, Result, SizeExpression, PtrExpression, Ctx, Status);
+ const Expr *SizeExpression,
+ const Expr *PtrExpression, ASTContext &Ctx,
+ EvalResult &Status) const {
+ return EvaluateCharRangeAsStringImpl(this, Result, SizeExpression,
+ PtrExpression, Ctx, Status);
}
bool Expr::tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const {
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 6e0d95714b..be4ba6878b 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -510,17 +510,18 @@ char GCCAsmStmt::AsmStringPiece::getModifier() const {
return isLetter(Str[0]) ? Str[0] : '\0';
}
-std::string GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(const Expr* E) {
- if(auto* SL = llvm::dyn_cast<StringLiteral>(E))
+std::string GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(const Expr *E) {
+ if (auto *SL = llvm::dyn_cast<StringLiteral>(E))
return SL->getString().str();
- assert(E->getDependence() == ExprDependence::None && "cannot extract a string from a dependent expression");
- auto* CE = cast<ConstantExpr>(E);
+ assert(E->getDependence() == ExprDependence::None &&
+ "cannot extract a string from a dependent expression");
+ auto *CE = cast<ConstantExpr>(E);
APValue Res = CE->getAPValueResult();
assert(Res.isArray() && "expected an array");
std::string Out;
Out.reserve(Res.getArraySize());
- for(unsigned I = 0; I < Res.getArraySize(); ++I) {
+ for (unsigned I = 0; I < Res.getArraySize(); ++I) {
APValue C = Res.getArrayInitializedElt(I);
assert(C.isInt());
auto Ch = static_cast<char>(C.getInt().getExtValue());
@@ -570,15 +571,10 @@ std::string GCCAsmStmt::getInputConstraint(unsigned i) const {
return ExtractStringFromGCCAsmStmtComponent(getInputConstraintExpr(i));
}
-void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C,
- IdentifierInfo **Names,
- Expr **Constraints,
- Stmt **Exprs,
- unsigned NumOutputs,
- unsigned NumInputs,
- unsigned NumLabels,
- Expr **Clobbers,
- unsigned NumClobbers) {
+void GCCAsmStmt::setOutputsAndInputsAndClobbers(
+ const ASTContext &C, IdentifierInfo **Names, Expr **Constraints,
+ Stmt **Exprs, unsigned NumOutputs, unsigned NumInputs, unsigned NumLabels,
+ Expr **Clobbers, unsigned NumClobbers) {
this->NumOutputs = NumOutputs;
this->NumInputs = NumInputs;
this->NumClobbers = NumClobbers;
@@ -596,11 +592,11 @@ void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C,
unsigned NumConstraints = NumOutputs + NumInputs;
C.Deallocate(this->Constraints);
- this->Constraints = new (C) Expr*[NumConstraints];
+ this->Constraints = new (C) Expr *[NumConstraints];
std::copy(Constraints, Constraints + NumConstraints, this->Constraints);
C.Deallocate(this->Clobbers);
- this->Clobbers = new (C) Expr*[NumClobbers];
+ this->Clobbers = new (C) Expr *[NumClobbers];
std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
}
@@ -766,15 +762,14 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
// (BeginLoc, EndLoc) represents the range of the operand we are currently
// processing. Unlike Str, the range includes the leading '%'.
SourceLocation BeginLoc, EndLoc;
- if(auto* SL = dyn_cast<StringLiteral>(getAsmStringExpr())) {
- BeginLoc = SL->getLocationOfByte(
- Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
- &LastAsmStringOffset);
- EndLoc = SL->getLocationOfByte(
- CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken,
- &LastAsmStringOffset);
- }
- else {
+ if (auto *SL = dyn_cast<StringLiteral>(getAsmStringExpr())) {
+ BeginLoc =
+ SL->getLocationOfByte(Percent - StrStart, SM, LO, TI,
+ &LastAsmStringToken, &LastAsmStringOffset);
+ EndLoc =
+ SL->getLocationOfByte(CurPtr - StrStart, SM, LO, TI,
+ &LastAsmStringToken, &LastAsmStringOffset);
+ } else {
BeginLoc = getAsmStringExpr()->getBeginLoc();
EndLoc = getAsmStringExpr()->getEndLoc();
}
@@ -809,15 +804,14 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
// (BeginLoc, EndLoc) represents the range of the operand we are currently
// processing. Unlike Str, the range includes the leading '%'.
SourceLocation BeginLoc, EndLoc;
- if(auto* SL = dyn_cast<StringLiteral>(getAsmStringExpr())) {
- BeginLoc = SL->getLocationOfByte(
- Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
- &LastAsmStringOffset);
- EndLoc = SL->getLocationOfByte(
- NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken,
- &LastAsmStringOffset);
- }
- else {
+ if (auto *SL = dyn_cast<StringLiteral>(getAsmStringExpr())) {
+ BeginLoc =
+ SL->getLocationOfByte(Percent - StrStart, SM, LO, TI,
+ &LastAsmStringToken, &LastAsmStringOffset);
+ EndLoc =
+ SL->getLocationOfByte(NameEnd + 1 - StrStart, SM, LO, TI,
+ &LastAsmStringToken, &LastAsmStringOffset);
+ } else {
BeginLoc = getAsmStringExpr()->getBeginLoc();
EndLoc = getAsmStringExpr()->getEndLoc();
}
@@ -900,13 +894,12 @@ void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
GCCAsmStmt::GCCAsmStmt(const ASTContext &C, SourceLocation asmloc,
bool issimple, bool isvolatile, unsigned numoutputs,
unsigned numinputs, IdentifierInfo **names,
- Expr **constraints, Expr **exprs,
- Expr *asmstr, unsigned numclobbers,
- Expr **clobbers, unsigned numlabels,
- SourceLocation rparenloc)
+ Expr **constraints, Expr **exprs, Expr *asmstr,
+ unsigned numclobbers, Expr **clobbers,
+ unsigned numlabels, SourceLocation rparenloc)
: AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
numinputs, numclobbers),
- RParenLoc(rparenloc), AsmStr(asmstr), NumLabels(numlabels) {
+ RParenLoc(rparenloc), AsmStr(asmstr), NumLabels(numlabels) {
unsigned NumExprs = NumOutputs + NumInputs + NumLabels;
Names = new (C) IdentifierInfo*[NumExprs];
@@ -916,10 +909,10 @@ GCCAsmStmt::GCCAsmStmt(const ASTContext &C, SourceLocation asmloc,
std::copy(exprs, exprs + NumExprs, Exprs);
unsigned NumConstraints = NumOutputs + NumInputs;
- Constraints = new (C) Expr*[NumConstraints];
+ Constraints = new (C) Expr *[NumConstraints];
std::copy(constraints, constraints + NumConstraints, Constraints);
- Clobbers = new (C) Expr*[NumClobbers];
+ Clobbers = new (C) Expr *[NumClobbers];
std::copy(clobbers, clobbers + NumClobbers, Clobbers);
}
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index c8623225b4..bceab177a6 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -497,8 +497,8 @@ void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
if (Policy.IncludeNewlines) OS << NL;
}
-static void PrintGCCAsmString(raw_ostream &OS, Expr*E) {
- if(E->getDependence()) {
+static void PrintGCCAsmString(raw_ostream &OS, Expr *E) {
+ if (E->getDependence()) {
OS << "<<dependent expr>>";
return;
}
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 6ef9625f75..c243d5c982 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2587,11 +2587,10 @@ static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect,
// Slap the source location of the inline asm into a !srcloc metadata on the
// call.
if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S)) {
- if(const StringLiteral* SL = dyn_cast<StringLiteral>(gccAsmStmt->getAsmStringExpr()))
- Result.setMetadata("srcloc",
- getAsmSrcLocInfo(SL, CGF));
- }
- else {
+ if (const StringLiteral *SL =
+ dyn_cast<StringLiteral>(gccAsmStmt->getAsmStringExpr()))
+ Result.setMetadata("srcloc", getAsmSrcLocInfo(SL, CGF));
+ } else {
// At least put the line number on MS inline asm blobs.
llvm::Constant *Loc =
llvm::ConstantInt::get(CGF.Int64Ty, S.getAsmLoc().getRawEncoding());
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index baf264c808..0875090149 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1670,32 +1670,30 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) {
ExprResult AsmString;
- if(isTokenStringLiteral()) {
+ if (isTokenStringLiteral()) {
AsmString = ParseStringLiteralExpression();
- if(AsmString.isInvalid())
+ if (AsmString.isInvalid())
return AsmString;
const auto *SL = cast<StringLiteral>(AsmString.get());
if (!SL->isOrdinary()) {
Diag(Tok, diag::err_asm_operand_wide_string_literal)
- << SL->isWide()
- << SL->getSourceRange();
+ << SL->isWide() << SL->getSourceRange();
return ExprError();
}
- }
- else if(!ForAsmLabel && getLangOpts().CPlusPlus11 && Tok.is(tok::l_paren)) {
+ } else if (!ForAsmLabel && getLangOpts().CPlusPlus11 &&
+ Tok.is(tok::l_paren)) {
ParenParseOption ExprType = SimpleExpr;
- SourceLocation RParenLoc;
+ SourceLocation RParenLoc;
ParsedType CastTy;
- AsmString = ParseParenExpression(ExprType, true/*stopIfCastExpr*/,
- false, CastTy, RParenLoc);
- if(!AsmString.isUsable())
+ AsmString = ParseParenExpression(ExprType, true /*stopIfCastExpr*/, false,
+ CastTy, RParenLoc);
+ if (!AsmString.isUsable())
return ExprError();
- }
- else {
+ } else {
Diag(Tok, diag::err_asm_expected_string)
- << /*and expression=*/(getLangOpts().CPlusPlus11? 0 : 1);
+ << /*and expression=*/(getLangOpts().CPlusPlus11 ? 0 : 1);
}
return Actions.ActOnGCCAsmStmtString(AsmString.get(), ForAsmLabel);
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 332099bbbd..dcd249e7a1 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -17262,11 +17262,10 @@ void Sema::DiagnoseStaticAssertDetails(const Expr *E) {
}
template <typename ResultType>
-static bool EvaluateAsStringImpl(Sema & SemaRef,
- Expr *Message,
- ResultType &Result, ASTContext &Ctx,
- Sema::StringEvaluationContext EvalContext,
- bool ErrorOnInvalidMessage) {
+static bool EvaluateAsStringImpl(Sema &SemaRef, Expr *Message,
+ ResultType &Result, ASTContext &Ctx,
+ Sema::StringEvaluationContext EvalContext,
+ bool ErrorOnInvalidMessage) {
assert(Message);
assert(!Message->isTypeDependent() && !Message->isValueDependent() &&
@@ -17274,20 +17273,21 @@ static bool EvaluateAsStringImpl(Sema & SemaRef,
if (const auto *SL = dyn_cast<StringLiteral>(Message)) {
assert(SL->isUnevaluated() && "expected an unevaluated string");
- if constexpr(std::is_same_v<APValue, ResultType>) {
- Result = APValue(APValue::UninitArray{}, SL->getLength(), SL->getLength());
- const ConstantArrayType *CAT = SemaRef.getASTContext().getAsConstantArrayType(SL->getType());
- assert(CAT && "string literal isn't an array");
- QualType CharType = CAT->getElementType();
- llvm::APSInt Value(SemaRef.getASTContext().getTypeSize(CharType),
- CharType->isUnsignedIntegerType());
- for(unsigned I = 0; I < SL->getLength(); I++) {
- Value = SL->getCodeUnit(I);
- Result.getArrayInitializedElt(I) = APValue(Value);
- }
- }
- else {
- Result.assign(SL->getString().begin(), SL->getString().end());
+ if constexpr (std::is_same_v<APValue, ResultType>) {
+ Result =
+ APValue(APValue::UninitArray{}, SL->getLength(), SL->getLength());
+ const ConstantArrayType *CAT =
+ SemaRef.getASTContext().getAsConstantArrayType(SL->getType());
+ assert(CAT && "string literal isn't an array");
+ QualType CharType = CAT->getElementType();
+ llvm::APSInt Value(SemaRef.getASTContext().getTypeSize(CharType),
+ CharType->isUnsignedIntegerType());
+ for (unsigned I = 0; I < SL->getLength(); I++) {
+ Value = SL->getCodeUnit(I);
+ Result.getArrayInitializedElt(I) = APValue(Value);
+ }
+ } else {
+ Result.assign(SL->getString().begin(), SL->getString().end());
}
return true;
}
@@ -17339,7 +17339,8 @@ static bool EvaluateAsStringImpl(Sema & SemaRef,
CXXScopeSpec(), SourceLocation(), nullptr, LR, nullptr, nullptr);
if (Res.isInvalid())
return ExprError();
- Res = SemaRef.BuildCallExpr(nullptr, Res.get(), Loc, {}, Loc, nullptr, false, true);
+ Res = SemaRef.BuildCallExpr(nullptr, Res.get(), Loc, {}, Loc, nullptr,
+ false, true);
if (Res.isInvalid())
return ExprError();
if (Res.get()->isTypeDependent() || Res.get()->isValueDependent())
@@ -17351,27 +17352,28 @@ static bool EvaluateAsStringImpl(Sema & SemaRef,
ExprResult DataE = BuildExpr(*DataMember);
QualType SizeT = SemaRef.Context.getSizeType();
- QualType ConstCharPtr =
- SemaRef.Context.getPointerType(SemaRef.Context.getConstType(SemaRef.Context.CharTy));
+ QualType ConstCharPtr = SemaRef.Context.getPointerType(
+ SemaRef.Context.getConstType(SemaRef.Context.CharTy));
ExprResult EvaluatedSize =
- SizeE.isInvalid() ? ExprError()
- : SemaRef.BuildConvertedConstantExpression(
- SizeE.get(), SizeT, Sema::CCEK_StaticAssertMessageSize);
+ SizeE.isInvalid()
+ ? ExprError()
+ : SemaRef.BuildConvertedConstantExpression(
+ SizeE.get(), SizeT, Sema::CCEK_StaticAssertMessageSize);
if (EvaluatedSize.isInvalid()) {
SemaRef.Diag(Loc, diag::err_user_defined_msg_invalid_mem_fn_ret_ty)
- << EvalContext << /*size*/ 0;
+ << EvalContext << /*size*/ 0;
return false;
}
ExprResult EvaluatedData =
DataE.isInvalid()
? ExprError()
- : SemaRef.BuildConvertedConstantExpression(DataE.get(), ConstCharPtr,
- Sema::CCEK_StaticAssertMessageData);
+ : SemaRef.BuildConvertedConstantExpression(
+ DataE.get(), ConstCharPtr, Sema::CCEK_StaticAssertMessageData);
if (EvaluatedData.isInvalid()) {
SemaRef.Diag(Loc, diag::err_user_defined_msg_invalid_mem_fn_ret_ty)
- << EvalContext << /*data*/ 1;
+ << EvalContext << /*data*/ 1;
return false;
}
@@ -17386,9 +17388,9 @@ static bool EvaluateAsStringImpl(Sema & SemaRef,
EvaluatedData.get(), Ctx, Status) ||
!Notes.empty()) {
SemaRef.Diag(Message->getBeginLoc(),
- ErrorOnInvalidMessage ? diag::err_user_defined_msg_constexpr
- : diag::warn_user_defined_msg_constexpr)
- << EvalContext;
+ ErrorOnInvalidMessage ? diag::err_user_defined_msg_constexpr
+ : diag::warn_user_defined_msg_constexpr)
+ << EvalContext;
for (const auto &Note : Notes)
SemaRef.Diag(Note.first, Note.second);
return !ErrorOnInvalidMessage;
@@ -17399,14 +17401,15 @@ static bool EvaluateAsStringImpl(Sema & SemaRef,
bool Sema::EvaluateAsString(Expr *Message, APValue &Result, ASTContext &Ctx,
StringEvaluationContext EvalContext,
bool ErrorOnInvalidMessage) {
- return EvaluateAsStringImpl(*this, Message, Result, Ctx, EvalContext, ErrorOnInvalidMessage);
-
+ return EvaluateAsStringImpl(*this, Message, Result, Ctx, EvalContext,
+ ErrorOnInvalidMessage);
}
bool Sema::EvaluateAsString(Expr *Message, std::string &Result, ASTContext &Ctx,
StringEvaluationContext EvalContext,
bool ErrorOnInvalidMessage) {
- return EvaluateAsStringImpl(*this, Message, Result, Ctx, EvalContext, ErrorOnInvalidMessage);
+ return EvaluateAsStringImpl(*this, Message, Result, Ctx, EvalContext,
+ ErrorOnInvalidMessage);
}
Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
@@ -17455,7 +17458,7 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
if (!Failed && AssertMessage && Cond.getBoolValue()) {
std::string Str;
EvaluateAsString(AssertMessage, Str, Context,
- StringEvaluationContext::StaticAssert,
+ StringEvaluationContext::StaticAssert,
/*ErrorOnInvalidMessage=*/false);
}
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index e168f57f8f..4507a21a4c 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -205,14 +205,14 @@ static StringRef extractRegisterName(const Expr *Expression,
// conflicted clobber, else returns nullptr
static SourceLocation
getClobberConflictLocation(MultiExprArg Exprs, Expr **Constraints,
- Expr **Clobbers, int NumClobbers,
- unsigned NumLabels,
+ Expr **Clobbers, int NumClobbers, unsigned NumLabels,
const TargetInfo &Target, ASTContext &Cont) {
llvm::StringSet<> InOutVars;
// Collect all the input and output registers from the extended asm
// statement in order to check for conflicts with the clobber list
for (unsigned int i = 0; i < Exprs.size() - NumLabels; ++i) {
- std::string Constraint = GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraints[i]);
+ std::string Constraint =
+ GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraints[i]);
StringRef InOutReg = Target.getConstraintRegister(
Constraint, extractRegisterName(Exprs[i], Target));
if (InOutReg != "")
@@ -221,7 +221,8 @@ getClobberConflictLocation(MultiExprArg Exprs, Expr **Constraints,
// Check for each item in the clobber list if it conflicts with the input
// or output
for (int i = 0; i < NumClobbers; ++i) {
- std::string Clobber = GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Clobbers[i]);
+ std::string Clobber =
+ GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Clobbers[i]);
// We only check registers, therefore we don't check cc and memory
// clobbers
if (Clobber == "cc" || Clobber == "memory" || Clobber == "unwind")
@@ -234,24 +235,24 @@ getClobberConflictLocation(MultiExprArg Exprs, Expr **Constraints,
return SourceLocation();
}
-ExprResult Sema::ActOnGCCAsmStmtString(Expr* Expr, bool ForAsmLabel) {
- if(!Expr)
+ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) {
+ if (!Expr)
return ExprError();
- if(auto* SL = dyn_cast<StringLiteral>(Expr)) {
+ if (auto *SL = dyn_cast<StringLiteral>(Expr)) {
assert(SL->isOrdinary());
if (ForAsmLabel && SL->getString().empty()) {
Diag(Expr->getBeginLoc(), diag::err_asm_operand_empty_string)
- << SL->getSourceRange();
+ << SL->getSourceRange();
}
return SL;
}
- if(DiagnoseUnexpandedParameterPack(Expr))
+ if (DiagnoseUnexpandedParameterPack(Expr))
return ExprError();
- if(Expr->getDependence() != ExprDependence::None)
+ if (Expr->getDependence() != ExprDependence::None)
return Expr;
APValue V;
- if(!EvaluateAsString(Expr, V, getASTContext(), StringEvaluationContext::Asm,
+ if (!EvaluateAsString(Expr, V, getASTContext(), StringEvaluationContext::Asm,
/*ErrorOnInvalid=*/true))
return ExprError();
@@ -259,7 +260,8 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr* Expr, bool ForAsmLabel) {
Diag(Expr->getBeginLoc(), diag::err_asm_operand_empty_string);
}
- ConstantExpr* Res = ConstantExpr::Create(getASTContext(), Expr, ConstantResultStorageKind::APValue);
+ ConstantExpr *Res = ConstantExpr::Create(getASTContext(), Expr,
+ ConstantResultStorageKind::APValue);
Res->SetResult(V, getASTContext());
return Res;
}
@@ -281,27 +283,28 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
auto CreateGCCAsmStmt = [&] {
return new (Context)
- GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
- NumInputs, Names, constraints.data(), Exprs.data(), asmString,
- NumClobbers, clobbers.data(), NumLabels, RParenLoc);
+ GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs,
+ Names, constraints.data(), Exprs.data(), asmString,
+ NumClobbers, clobbers.data(), NumLabels, RParenLoc);
};
- if(asmString->getDependence() != ExprDependence::None
- || llvm::any_of(constraints, [] (Expr* E) {
+ if (asmString->getDependence() != ExprDependence::None ||
+ llvm::any_of(
+ constraints,
+ [](Expr *E) { return E->getDependence() != ExprDependence::None; }) ||
+ llvm::any_of(clobbers, [](Expr *E) {
return E->getDependence() != ExprDependence::None;
- })
- || llvm::any_of(clobbers, [] (Expr* E) {
- return E->getDependence() != ExprDependence::None;
- }))
- return CreateGCCAsmStmt();
+ }))
+ return CreateGCCAsmStmt();
for (unsigned i = 0; i != NumOutputs; i++) {
- Expr* Constraint = constraints[i];
+ Expr *Constraint = constraints[i];
StringRef OutputName;
if (Names[i])
OutputName = Names[i]->getName();
- std::string ConstraintStr = GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint);
+ std::string ConstraintStr =
+ GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint);
TargetInfo::ConstraintInfo Info(ConstraintStr, OutputName);
if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
@@ -372,7 +375,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
unsigned Size = Context.getTypeSize(OutputExpr->getType());
if (!Context.getTargetInfo().validateOutputSize(
- FeatureMap, GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint), Size)) {
+ FeatureMap,
+ GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint),
+ Size)) {
targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
<< Info.getConstraintStr();
return CreateGCCAsmStmt();
@@ -388,12 +393,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
if (Names[i])
InputName = Names[i]->getName();
- std::string ConstraintStr = GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint);
+ std::string ConstraintStr =
+ GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint);
TargetInfo::ConstraintInfo Info(ConstraintStr, InputName);
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
Info)) {
- targetDiag(Constraint->getBeginLoc(), diag::err_asm_invalid_input_constraint)
+ targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_input_constraint)
<< Info.getConstraintStr();
return CreateGCCAsmStmt();
}
@@ -480,8 +487,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
return StmtError();
unsigned Size = Context.getTypeSize(Ty);
- if (!Context.getTargetInfo().validateInputSize(FeatureMap,
- ConstraintStr, Size))
+ if (!Context.getTargetInfo().validateInputSize(FeatureMap, ConstraintStr,
+ Size))
return targetDiag(InputExpr->getBeginLoc(),
diag::err_asm_invalid_input_size)
<< Info.getConstraintStr();
@@ -493,15 +500,17 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
for (unsigned i = 0; i != NumClobbers; i++) {
Expr *ClobberExpr = clobbers[i];
- std::string Clobber = GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
+ std::string Clobber =
+ GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
if (!Context.getTargetInfo().isValidClobber(Clobber)) {
- targetDiag(ClobberExpr->getBeginLoc(), diag::err_asm_unknown_register_name)
+ targetDiag(ClobberExpr->getBeginLoc(),
+ diag::err_asm_unknown_register_name)
<< Clobber;
- return new (Context)
- GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
- NumInputs, Names, constraints.data(), Exprs.data(), asmString,
- NumClobbers, clobbers.data(), NumLabels, RParenLoc);
+ return new (Context) GCCAsmStmt(
+ Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
+ constraints.data(), Exprs.data(), asmString, NumClobbers,
+ clobbers.data(), NumLabels, RParenLoc);
}
if (Clobber == "unwind") {
@@ -519,8 +528,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
// Validate the asm string, ensuring it makes sense given the operands we
// have.
- auto GetLocation = [this](const Expr* Str, unsigned Offset) {
- if(auto* SL = dyn_cast<StringLiteral>(Str))
+ auto GetLocation = [this](const Expr *Str, unsigned Offset) {
+ if (auto *SL = dyn_cast<StringLiteral>(Str))
return getLocationOfStringLiteralByte(SL, Offset);
return Str->getBeginLoc();
};
@@ -568,8 +577,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
unsigned Size = Context.getTypeSize(Ty);
std::string SuggestedModifier;
if (!Context.getTargetInfo().validateConstraintModifier(
- GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint), Piece.getModifier(), Size,
- SuggestedModifier)) {
+ GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint),
+ Piece.getModifier(), Size, SuggestedModifier)) {
targetDiag(Exprs[ConstraintIdx]->getBeginLoc(),
diag::warn_asm_mismatched_size_modifier);
@@ -577,9 +586,10 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
auto B = targetDiag(Piece.getRange().getBegin(),
diag::note_asm_missing_constraint_modifier)
<< SuggestedModifier;
- if(isa<StringLiteral>(Constraint)) {
+ if (isa<StringLiteral>(Constraint)) {
SuggestedModifier = "%" + SuggestedModifier + Piece.getString();
- B << FixItHint::CreateReplacement(Piece.getRange(), SuggestedModifier);
+ B << FixItHint::CreateReplacement(Piece.getRange(),
+ SuggestedModifier);
}
}
}
@@ -740,10 +750,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
}
// Check for conflicts between clobber list and input or output lists
- SourceLocation ConstraintLoc =
- getClobberConflictLocation(Exprs, constraints.data(), clobbers.data(), NumClobbers,
- NumLabels,
- Context.getTargetInfo(), Context);
+ SourceLocation ConstraintLoc = getClobberConflictLocation(
+ Exprs, constraints.data(), clobbers.data(), NumClobbers, NumLabels,
+ Context.getTargetInfo(), Context);
if (ConstraintLoc.isValid())
targetDiag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber);
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 06d41a8154..8cf82a4c33 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -8552,7 +8552,6 @@ template<typename Derived>
StmtResult
TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
-
SmallVector<Expr*, 8> Constraints;
SmallVector<Expr*, 8> Exprs;
SmallVector<IdentifierInfo *, 4> Names;
@@ -8561,15 +8560,15 @@ TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
bool ExprsChanged = false;
- auto RebuildString = [&] (Expr* E) {
- ExprResult Result = getDerived().TransformExpr(E);
- if (Result.isInvalid())
- return Result;
- if(!Result.isInvalid() && Result.get() != E) {
- ExprsChanged = true;
- Result = SemaRef.ActOnGCCAsmStmtString(Result.get(), /*ForLabel=*/false);
- }
+ auto RebuildString = [&](Expr *E) {
+ ExprResult Result = getDerived().TransformExpr(E);
+ if (Result.isInvalid())
return Result;
+ if (!Result.isInvalid() && Result.get() != E) {
+ ExprsChanged = true;
+ Result = SemaRef.ActOnGCCAsmStmtString(Result.get(), /*ForLabel=*/false);
+ }
+ return Result;
};
// Go through the outputs.
@@ -8627,10 +8626,10 @@ TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
// Go through the clobbers.
for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
- ExprResult Result = RebuildString(S->getClobberExpr(I));
- if (Result.isInvalid())
- return StmtError();
- Clobbers.push_back(Result.get());
+ ExprResult Result = RebuildString(S->getClobberExpr(I));
+ if (Result.isInvalid())
+ return StmtError();
+ Clobbers.push_back(Result.get());
}
ExprResult AsmString = RebuildString(S->getAsmStringExpr());
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 7ad1216cb5..2db7d9346c 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -390,7 +390,7 @@ void ASTStmtReader::VisitGCCAsmStmt(GCCAsmStmt *S) {
// Outputs and inputs
SmallVector<IdentifierInfo *, 16> Names;
- SmallVector<Expr*, 16> Constraints;
+ SmallVector<Expr *, 16> Constraints;
SmallVector<Stmt*, 16> Exprs;
for (unsigned I = 0, N = NumOutputs + NumInputs; I != N; ++I) {
Names.push_back(Record.readIdentifier());
@@ -399,7 +399,7 @@ void ASTStmtReader::VisitGCCAsmStmt(GCCAsmStmt *S) {
}
// Constraints
- SmallVector<Expr*, 16> Clobbers;
+ SmallVector<Expr *, 16> Clobbers;
for (unsigned I = 0; I != NumClobbers; ++I)
Clobbers.push_back(cast_or_null<Expr>(Record.readSubStmt()));
``````````
</details>
https://github.com/llvm/llvm-project/pull/131003
More information about the cfe-commits
mailing list