[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