[clang] Fix incorrect array initialization with string literal (fixes #112189) (PR #156846)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 6 03:09:49 PDT 2025
================
@@ -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
----------------
awson wrote:
Done
https://github.com/llvm/llvm-project/pull/156846
More information about the cfe-commits
mailing list