================
@@ -168,16 +168,95 @@ bool Sema::IsStringInit(Expr *Init, const ArrayType *AT) {
   return ::IsStringInit(Init, AT, Context) == SIF_None;
 }
 
+static StringLiteral *CloneStringLiteral(const StringLiteral *SL,
+                                         ASTContext &C) {
+  SourceLocation *SLocs = new (C) SourceLocation[SL->getNumConcatenated()];
+  std::copy(SL->tokloc_begin(), SL->tokloc_end(), SLocs);
+  return StringLiteral::Create(
+      C, SL->getBytes(), SL->getKind(), SL->isPascal(), SL->getType(),
+      ArrayRef<SourceLocation>(SLocs, SL->getNumConcatenated()));
+}
+
+// Exactly follow `IgnoreParensSingleStep` (`AST/IgnoreExpr.h`)
+// We only clone those subexpressions which `IgnoreParensSingleStep` drills 
down
+// to.
+static Expr *CloneDrilled(Expr *E, ASTContext &C) {
+  if (auto *SL = dyn_cast<StringLiteral>(E)) {
+    return CloneStringLiteral(SL, C);
+  }
+
+  if (auto *PE = dyn_cast<ParenExpr>(E)) {
+    return new (C) ParenExpr(PE->getBeginLoc(), PE->getEndLoc(),
+                             CloneDrilled(PE->getSubExpr(), C));
+  }
+
+  if (auto *UO = dyn_cast<UnaryOperator>(E)) {
+    if (UO->getOpcode() == UO_Extension) {
+      return UnaryOperator::Create(
+          C, CloneDrilled(UO->getSubExpr(), C), UO_Extension, UO->getType(),
+          UO->getValueKind(), UO->getObjectKind(), UO->getBeginLoc(),
+          UO->canOverflow(), UO->getFPOptionsOverride());
+    }
+  }
+
+  else if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) {
+    if (!GSE->isResultDependent()) {
+      ArrayRef<Expr *> GSEAEs = GSE->getAssocExprs();
+      Expr **NewGSEAEs = new (C) Expr *[GSEAEs.size()];
+      std::copy(GSEAEs.begin(), GSEAEs.end(), NewGSEAEs);
+      NewGSEAEs[GSE->getResultIndex()] = CloneDrilled(GSE->getResultExpr(), C);
+
+#define CREATE_GSE(ctrl)                                                       
\
+  GenericSelectionExpr::Create(                                                
\
+      C, GSE->getGenericLoc(), ctrl, GSE->getAssocTypeSourceInfos(),           
\
+      ArrayRef<Expr *>(NewGSEAEs, GSEAEs.size()), GSE->getDefaultLoc(),        
\
+      GSE->getRParenLoc(), GSE->containsUnexpandedParameterPack(),             
\
+      GSE->getResultIndex())
+
+      return GSE->isExprPredicate() ? CREATE_GSE(GSE->getControllingExpr())
+                                    : CREATE_GSE(GSE->getControllingType());
+#undef CREATE_GSE
+    }
+  }
+
+  else if (auto *CE = dyn_cast<ChooseExpr>(E)) {
+    if (!CE->isConditionDependent()) {
+      // Drills to `CE->getChosenSubExpr()`
+      const bool isCondTrue = CE->isConditionTrue();
+      return new (C)
+          ChooseExpr(CE->getBeginLoc(), CE->getCond(),
+                     isCondTrue ? CloneDrilled(CE->getLHS(), C) : CE->getLHS(),
+                     isCondTrue ? CE->getRHS() : CloneDrilled(CE->getRHS(), C),
+                     CE->getType(), CE->getValueKind(), CE->getObjectKind(),
+                     CE->getRParenLoc(), CE->isConditionTrue());
+    }
+  }
+
+  else if (auto *PE = dyn_cast<PredefinedExpr>(E)) {
+    if (PE->isTransparent() && PE->getFunctionName()) {
+      return PredefinedExpr::Create(
+          C, PE->getLocation(), PE->getType(), PE->getIdentKind(),
+          PE->isTransparent(), CloneStringLiteral(PE->getFunctionName(), C));
+    }
+  }
+
+  return E;
+}
+
 /// Update the type of a string literal, including any surrounding parentheses,
 /// to match the type of the object which it is initializing.
-static void updateStringLiteralType(Expr *E, QualType Ty) {
+static Expr *updateStringLiteralType(Expr *E, QualType Ty, Sema &S) {
+  Expr *ENew = CloneDrilled(E, S.Context);
+  E = ENew;
+
   while (true) {
     E->setType(Ty);
     E->setValueKind(VK_PRValue);
     if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E))
       break;
     E = IgnoreParensSingleStep(E);
   }
+  return ENew;
----------------
awson wrote:

Nope.

We need to keep `ENew` for return.

`E` drills down to innermost string literal.

https://github.com/llvm/llvm-project/pull/156846
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to