From 248f3ded0f344b9b10acfb1f1fdf4a229d423e17 Mon Sep 17 00:00:00 2001 From: Youngsuk Kim Date: Tue, 16 Jul 2024 09:45:25 -0400 Subject: [PATCH] [clang] Prevent dangling StringRefs (#98699) Summary: Fix locations where dangling StringRefs are created. * `ConstraintSatisfaction::SubstitutionDiagnostic`: typedef of `std::pair` * `concepts::Requirement::SubstitutionDiagnostic`: struct whose 1st and 3rd data members are `StringRef`s Fixes #98667 Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251531 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Serialization/ASTReaderStmt.cpp | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 615e8879ac4744..cb96c5a16f261b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -826,6 +826,8 @@ Bug Fixes in This Version - ``__is_trivially_equality_comparable`` no longer returns true for types which have a constrained defaulted comparison operator (#GH89293). +- Fixed Clang from generating dangling StringRefs when deserializing Exprs & Stmts (#GH98667) + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 37f5c7f2bf20b8..7a3b81fc358aca 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -785,6 +785,12 @@ void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { E->setRParenLoc(readSourceLocation()); } +static StringRef saveStrToCtx(const std::string &S, ASTContext &Ctx) { + char *Buf = new (Ctx) char[S.size()]; + std::copy(S.begin(), S.end(), Buf); + return StringRef(Buf, S.size()); +} + static ConstraintSatisfaction readConstraintSatisfaction(ASTRecordReader &Record) { ConstraintSatisfaction Satisfaction; @@ -795,7 +801,9 @@ readConstraintSatisfaction(ASTRecordReader &Record) { for (unsigned i = 0; i != NumDetailRecords; ++i) { if (/* IsDiagnostic */Record.readInt()) { SourceLocation DiagLocation = Record.readSourceLocation(); - std::string DiagMessage = Record.readString(); + StringRef DiagMessage = + saveStrToCtx(Record.readString(), Record.getContext()); + Satisfaction.Details.emplace_back( new (Record.getContext()) ConstraintSatisfaction::SubstitutionDiagnostic(DiagLocation, @@ -820,9 +828,13 @@ void ASTStmtReader::VisitConceptSpecializationExpr( static concepts::Requirement::SubstitutionDiagnostic * readSubstitutionDiagnostic(ASTRecordReader &Record) { - std::string SubstitutedEntity = Record.readString(); + StringRef SubstitutedEntity = + saveStrToCtx(Record.readString(), Record.getContext()); + SourceLocation DiagLoc = Record.readSourceLocation(); - std::string DiagMessage = Record.readString(); + StringRef DiagMessage = + saveStrToCtx(Record.readString(), Record.getContext()); + return new (Record.getContext()) concepts::Requirement::SubstitutionDiagnostic{SubstitutedEntity, DiagLoc, DiagMessage};