https://github.com/abhina-sree updated https://github.com/llvm/llvm-project/pull/169803
>From 5142bd699c604228bb8ef2be06d928fe3cd5e933 Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Fri, 8 May 2026 12:17:22 -0400 Subject: [PATCH 01/10] add ParserConversionAction, do not translate unevaluated strings --- clang/include/clang/Parse/Parser.h | 1 + clang/include/clang/Sema/Sema.h | 4 +++- clang/lib/Parse/ParseDecl.cpp | 9 +++++++++ clang/lib/Parse/ParseExpr.cpp | 6 +++--- clang/lib/Parse/Parser.cpp | 4 ++++ clang/lib/Sema/SemaExpr.cpp | 8 ++++---- clang/test/CodeGen/systemz-charset-diag.cpp | 8 ++++++++ clang/test/CodeGen/systemz-charset.c | 5 +++++ 8 files changed, 37 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 163aa483a84e3..824c97d048df1 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -5716,6 +5716,7 @@ class Parser : public CodeCompletionHandler { bool Finished; }; ObjCImplParsingDataRAII *CurParsedObjCImpl; + ConversionAction ParserConversionAction; /// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them /// for later parsing. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b1d2488d2163b..8ff9cba3ead47 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -54,6 +54,7 @@ #include "clang/Basic/StackExhaustionHandler.h" #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TokenKinds.h" +#include "clang/Lex/TextEncoding.h" #include "clang/Sema/AnalysisBasedWarnings.h" #include "clang/Sema/Attr.h" #include "clang/Sema/CleanupInfo.h" @@ -7397,7 +7398,8 @@ class Sema final : public SemaBase { /// from multiple tokens. However, the common case is that StringToks points /// to one string. ExprResult ActOnStringLiteral(ArrayRef<Token> StringToks, - Scope *UDLScope = nullptr); + Scope *UDLScope = nullptr, + ConversionAction Action = CA_ToLiteralEncoding); ExprResult ActOnUnevaluatedStringLiteral(ArrayRef<Token> StringToks); diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 2bbc76fc7c4df..8475143c69b36 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -565,6 +565,9 @@ unsigned Parser::ParseAttributeArgsCommon( nullptr, Sema::ExpressionEvaluationContextRecord::EK_AttrArgument); + SaveAndRestore<ConversionAction> SavedTranslationState( + ParserConversionAction, CA_NoConversion); + ExprResult ArgExpr = ParseAssignmentExpression(); if (ArgExpr.isInvalid()) { SkipUntil(tok::r_paren, StopAtSemi); @@ -645,6 +648,9 @@ void Parser::ParseGNUAttributeArgs( ParsedAttr::Kind AttrKind = ParsedAttr::getParsedKind(AttrName, ScopeName, Form.getSyntax()); + SaveAndRestore<ConversionAction> SavedTranslationState(ParserConversionAction, + CA_NoConversion); + if (AttrKind == ParsedAttr::AT_Availability) { ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ScopeLoc, Form); @@ -724,6 +730,9 @@ unsigned Parser::ParseClangAttributeArgs( ParsedAttr::Kind AttrKind = ParsedAttr::getParsedKind(AttrName, ScopeName, Form.getSyntax()); + SaveAndRestore<ConversionAction> SavedTranslationState(ParserConversionAction, + CA_NoConversion); + switch (AttrKind) { default: return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 87cd7a01451cf..06482f6b65426 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -3041,9 +3041,9 @@ ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral, } // Pass the set of string tokens, ready for concatenation, to the actions. - return Actions.ActOnStringLiteral(StringToks, - AllowUserDefinedLiteral ? getCurScope() - : nullptr); + return Actions.ActOnStringLiteral( + StringToks, AllowUserDefinedLiteral ? getCurScope() : nullptr, + ParserConversionAction); } ExprResult Parser::ParseGenericSelectionExpression() { diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index d83b75072f844..72c6808d51716 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -70,6 +70,8 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies) NumCachedScopes = 0; CurParsedObjCImpl = nullptr; + ParserConversionAction = CA_ToLiteralEncoding; + // Add #pragma handlers. These are removed and destroyed in the // destructor. initializePragmaHandlers(); @@ -1552,6 +1554,8 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { } ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) { + SaveAndRestore<ConversionAction> SavedTranslationState(ParserConversionAction, + CA_NoConversion); ExprResult AsmString; if (isTokenStringLiteral()) { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 90e360e2b05fc..c02b8b1d3643d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2259,8 +2259,8 @@ Sema::ExpandFunctionLocalPredefinedMacros(ArrayRef<Token> Toks) { return ExpandedToks; } -ExprResult -Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) { +ExprResult Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope, + ConversionAction Action) { assert(!StringToks.empty() && "Must have at least one string!"); // StringToks needs backing storage as it doesn't hold array elements itself @@ -2268,8 +2268,8 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) { if (getLangOpts().MicrosoftExt) StringToks = ExpandedToks = ExpandFunctionLocalPredefinedMacros(StringToks); - StringLiteralParser Literal( - StringToks, PP, StringLiteralEvalMethod::Evaluated, CA_ToLiteralEncoding); + StringLiteralParser Literal(StringToks, PP, + StringLiteralEvalMethod::Evaluated, Action); if (Literal.hadError) return ExprError(); diff --git a/clang/test/CodeGen/systemz-charset-diag.cpp b/clang/test/CodeGen/systemz-charset-diag.cpp index 4ed94810150a3..ad08e1f391214 100644 --- a/clang/test/CodeGen/systemz-charset-diag.cpp +++ b/clang/test/CodeGen/systemz-charset-diag.cpp @@ -1,3 +1,11 @@ // RUN: %clang_cc1 -triple s390x-none-zos -fexec-charset IBM-1047 %s -std=c++17 -emit-llvm -o - -verify const char* Computer = "🖥️"; // expected-error-re {{conversion to literal encoding failed: {{.*}}}} + +static_assert(false, "Error string"); // expected-error {{static assertion failed: Error string}} + +[[deprecated("message")]] void test_deprecated() {return;} // expected-note {{'test_deprecated' has been explicitly marked deprecated here}} + +int main() { + test_deprecated(); // expected-warning {{'test_deprecated' is deprecated: message}} +} diff --git a/clang/test/CodeGen/systemz-charset.c b/clang/test/CodeGen/systemz-charset.c index 766b6a83f00ff..e0d1736bf853f 100644 --- a/clang/test/CodeGen/systemz-charset.c +++ b/clang/test/CodeGen/systemz-charset.c @@ -66,3 +66,8 @@ const char* hello_macro = HELLO; const char* preprocessor_concatenation = HELLO_WORLD; //CHECK: c"\C8\85\93\93\96@\E6\96\99\93\84Z\00" //CHECK-UTF8: c"Hello World!\00" + +void asm_labeled_fn(void) __asm__("asm_sym"); +void asm_labeled_fn(void) {} +//CHECK: define{{.*}} void @asm_sym( +//CHECK-UTF8: define{{.*}} void @asm_sym( >From e1e45679032c206172b0e650be5939519fb43a8a Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Fri, 3 Jul 2026 14:52:22 -0400 Subject: [PATCH 02/10] remove unnecessary changes --- clang/lib/Parse/ParseDecl.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 8475143c69b36..2bbc76fc7c4df 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -565,9 +565,6 @@ unsigned Parser::ParseAttributeArgsCommon( nullptr, Sema::ExpressionEvaluationContextRecord::EK_AttrArgument); - SaveAndRestore<ConversionAction> SavedTranslationState( - ParserConversionAction, CA_NoConversion); - ExprResult ArgExpr = ParseAssignmentExpression(); if (ArgExpr.isInvalid()) { SkipUntil(tok::r_paren, StopAtSemi); @@ -648,9 +645,6 @@ void Parser::ParseGNUAttributeArgs( ParsedAttr::Kind AttrKind = ParsedAttr::getParsedKind(AttrName, ScopeName, Form.getSyntax()); - SaveAndRestore<ConversionAction> SavedTranslationState(ParserConversionAction, - CA_NoConversion); - if (AttrKind == ParsedAttr::AT_Availability) { ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ScopeLoc, Form); @@ -730,9 +724,6 @@ unsigned Parser::ParseClangAttributeArgs( ParsedAttr::Kind AttrKind = ParsedAttr::getParsedKind(AttrName, ScopeName, Form.getSyntax()); - SaveAndRestore<ConversionAction> SavedTranslationState(ParserConversionAction, - CA_NoConversion); - switch (AttrKind) { default: return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, >From 19dbec5de802b7d47b2dab358a180dc91640cb54 Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Thu, 9 Jul 2026 13:25:39 -0400 Subject: [PATCH 03/10] remove ParserConversionAction, add paramter to ParseStringLiteralExpression instead, add conversion to SystemCharset then back to UTF8 to handle escape sequences in system encoding --- clang/include/clang/Basic/TargetInfo.h | 3 ++ clang/include/clang/Lex/TextEncoding.h | 11 ++++++-- clang/include/clang/Parse/Parser.h | 6 ++-- clang/lib/Basic/TargetInfo.cpp | 2 ++ clang/lib/Frontend/CompilerInstance.cpp | 4 +-- clang/lib/Lex/TextEncoding.cpp | 37 +++++++++++++++++++++---- clang/lib/Parse/ParseExpr.cpp | 6 ++-- clang/lib/Parse/Parser.cpp | 8 ++---- clang/lib/Sema/SemaStmtAsm.cpp | 8 ++++++ clang/test/CodeGen/systemz-charset.c | 6 ++-- 10 files changed, 67 insertions(+), 24 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 6311b6b567a5e..dba50e03cc6d6 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -38,6 +38,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Error.h" +#include "llvm/Support/TextEncoding.h" #include "llvm/Support/VersionTuple.h" #include "llvm/TargetParser/Triple.h" #include <cassert> @@ -329,6 +330,8 @@ class TargetInfo : public TransferrableTargetInfo, virtual ~TargetInfo(); + std::unique_ptr<llvm::TextEncodingConverter> TargetStrConverter; + /// Retrieve the target options. TargetOptions &getTargetOpts() const { assert(TargetOpts && "Missing target options"); diff --git a/clang/include/clang/Lex/TextEncoding.h b/clang/include/clang/Lex/TextEncoding.h index 55663cdc072da..02cb16cef9f1b 100644 --- a/clang/include/clang/Lex/TextEncoding.h +++ b/clang/include/clang/Lex/TextEncoding.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_LEX_TEXTENCODING_H #include "clang/Basic/LangOptions.h" +#include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringRef.h" namespace llvm { @@ -17,16 +18,22 @@ class TextEncodingConverter; } // namespace llvm namespace clang { -enum ConversionAction { CA_NoConversion, CA_ToLiteralEncoding }; +enum ConversionAction { + CA_NoConversion, + CA_ToSystemEncoding, + CA_ToLiteralEncoding +}; class TextEncoding { llvm::StringRef LiteralEncoding; std::unique_ptr<llvm::TextEncodingConverter> ToLiteralEncodingConverter; + std::unique_ptr<llvm::TextEncodingConverter> ToSystemEncodingConverter; public: llvm::TextEncodingConverter *getConverter(ConversionAction Action) const; static std::error_code - setConvertersFromOptions(TextEncoding &TE, const clang::LangOptions &Opts); + setConvertersFromOptions(TextEncoding &TE, const clang::LangOptions &Opts, + clang::TargetInfo &TInfo); llvm::StringRef getLiteralEncoding() { return LiteralEncoding; } }; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 824c97d048df1..92c700114420c 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3867,8 +3867,9 @@ class Parser : public CodeCompletionHandler { /// associated with the class's definition. void PopParsingClass(Sema::ParsingClassState); - ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral, - bool Unevaluated); + ExprResult + ParseStringLiteralExpression(bool AllowUserDefinedLiteral, bool Unevaluated, + ConversionAction CA = CA_ToLiteralEncoding); /// This routine is called when the '@' is seen and consumed. /// Current token is an Identifier and is not a 'try'. This @@ -5716,7 +5717,6 @@ class Parser : public CodeCompletionHandler { bool Finished; }; ObjCImplParsingDataRAII *CurParsedObjCImpl; - ConversionAction ParserConversionAction; /// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them /// for later parsing. diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 1bb0026d8422e..1cc49cf84ce4c 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -198,6 +198,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { MaxOpenCLWorkGroupSize = 1024; MaxBitIntWidth.reset(); + + TargetStrConverter = nullptr; } // Out of line virtual dtor for TargetInfo. diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 66662a786e6fc..5179696041b66 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -563,8 +563,8 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { if (GetDependencyDirectives) PP->setDependencyDirectivesGetter(*GetDependencyDirectives); - if (auto EC = TextEncoding::setConvertersFromOptions(PP->getTextEncoding(), - getLangOpts())) + if (auto EC = TextEncoding::setConvertersFromOptions( + PP->getTextEncoding(), getLangOpts(), getTarget())) PP->getDiagnostics().Report(clang::diag::err_fe_text_encoding_config) << PP->getTextEncoding().getLiteralEncoding(); } diff --git a/clang/lib/Lex/TextEncoding.cpp b/clang/lib/Lex/TextEncoding.cpp index eb4fde8928a68..effd05185faf7 100644 --- a/clang/lib/Lex/TextEncoding.cpp +++ b/clang/lib/Lex/TextEncoding.cpp @@ -17,6 +17,8 @@ TextEncoding::getConverter(ConversionAction Action) const { switch (Action) { case CA_ToLiteralEncoding: return ToLiteralEncodingConverter.get(); + case CA_ToSystemEncoding: + return ToSystemEncodingConverter.get(); default: return nullptr; } @@ -24,23 +26,46 @@ TextEncoding::getConverter(ConversionAction Action) const { std::error_code TextEncoding::setConvertersFromOptions(TextEncoding &TE, - const clang::LangOptions &Opts) { + const clang::LangOptions &Opts, + clang::TargetInfo &TInfo) { using namespace llvm; const char *UTF8 = "UTF-8"; TE.LiteralEncoding = Opts.LiteralEncoding.empty() ? UTF8 : Opts.LiteralEncoding.c_str(); - // Create converter between internal and literal encoding specified - // in fexec-charset option. - if (TE.LiteralEncoding == UTF8) + if (TE.LiteralEncoding != UTF8) { + ErrorOr<TextEncodingConverter> ErrorOrLiteralConverter = + llvm::TextEncodingConverter::create(UTF8, TE.LiteralEncoding); + if (ErrorOrLiteralConverter) + TE.ToLiteralEncodingConverter = std::make_unique<TextEncodingConverter>( + std::move(*ErrorOrLiteralConverter)); + else + return ErrorOrLiteralConverter.getError(); + } + + if (TInfo.getDefaultOrdinaryLiteralEncoding() == UTF8) return std::error_code(); + + // Create converter between internal and default ordinary encoding for the + // target ErrorOr<TextEncodingConverter> ErrorOrConverter = - llvm::TextEncodingConverter::create(UTF8, TE.LiteralEncoding); + llvm::TextEncodingConverter::create( + UTF8, TInfo.getDefaultOrdinaryLiteralEncoding()); + if (ErrorOrConverter) + TE.ToSystemEncodingConverter = + std::make_unique<TextEncodingConverter>(std::move(*ErrorOrConverter)); + else + return ErrorOrConverter.getError(); + + ErrorOrConverter = llvm::TextEncodingConverter::create( + TInfo.getDefaultOrdinaryLiteralEncoding(), UTF8); + if (ErrorOrConverter) - TE.ToLiteralEncodingConverter = + TInfo.TargetStrConverter = std::make_unique<TextEncodingConverter>(std::move(*ErrorOrConverter)); else return ErrorOrConverter.getError(); + return std::error_code(); } diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 06482f6b65426..e7830c536f7a7 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -3021,7 +3021,8 @@ ExprResult Parser::ParseUnevaluatedStringLiteralExpression() { } ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral, - bool Unevaluated) { + bool Unevaluated, + ConversionAction CA) { assert(tokenIsLikeStringLiteral(Tok, getLangOpts()) && "Not a string-literal-like token!"); @@ -3042,8 +3043,7 @@ ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral, // Pass the set of string tokens, ready for concatenation, to the actions. return Actions.ActOnStringLiteral( - StringToks, AllowUserDefinedLiteral ? getCurScope() : nullptr, - ParserConversionAction); + StringToks, AllowUserDefinedLiteral ? getCurScope() : nullptr, CA); } ExprResult Parser::ParseGenericSelectionExpression() { diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 72c6808d51716..d6856206d900b 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -70,8 +70,6 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies) NumCachedScopes = 0; CurParsedObjCImpl = nullptr; - ParserConversionAction = CA_ToLiteralEncoding; - // Add #pragma handlers. These are removed and destroyed in the // destructor. initializePragmaHandlers(); @@ -1554,12 +1552,12 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { } ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) { - SaveAndRestore<ConversionAction> SavedTranslationState(ParserConversionAction, - CA_NoConversion); ExprResult AsmString; if (isTokenStringLiteral()) { - AsmString = ParseStringLiteralExpression(); + AsmString = ParseStringLiteralExpression(/*AllowUserDefinedLiteral=*/false, + /*Unevaluated=*/false, + CA_ToSystemEncoding); if (AsmString.isInvalid()) return AsmString; diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 6bf12d9cd98da..f1aab455b4411 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -245,6 +245,14 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) { Diag(Expr->getBeginLoc(), diag::err_asm_operand_empty_string) << SL->getSourceRange(); } + if (Context.getTargetInfo().TargetStrConverter) { + SmallString<16> ConvertedAsm; + Context.getTargetInfo().TargetStrConverter->convert(SL->getString(), + ConvertedAsm); + return StringLiteral::Create(Context, ConvertedAsm, + StringLiteralKind::Ordinary, + /*Pascal*/ false, {}, SL->getBeginLoc()); + } return SL; } if (DiagnoseUnexpandedParameterPack(Expr)) diff --git a/clang/test/CodeGen/systemz-charset.c b/clang/test/CodeGen/systemz-charset.c index e0d1736bf853f..f3bb1055ddf5e 100644 --- a/clang/test/CodeGen/systemz-charset.c +++ b/clang/test/CodeGen/systemz-charset.c @@ -67,7 +67,7 @@ const char* preprocessor_concatenation = HELLO_WORLD; //CHECK: c"\C8\85\93\93\96@\E6\96\99\93\84Z\00" //CHECK-UTF8: c"Hello World!\00" -void asm_labeled_fn(void) __asm__("asm_sym"); +void asm_labeled_fn(void) __asm__("\174asm_sym"); void asm_labeled_fn(void) {} -//CHECK: define{{.*}} void @asm_sym( -//CHECK-UTF8: define{{.*}} void @asm_sym( +//CHECK: define{{.*}}void @"@asm_sym"( +//CHECK-UTF8: define{{.*}}void @"@asm_sym"( >From c9e99a9bfc1dc844e7149b048abb5ef170f76627 Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Fri, 10 Jul 2026 15:07:07 -0400 Subject: [PATCH 04/10] address comments, attempt to fix CI --- clang/include/clang/Basic/TargetInfo.h | 2 +- clang/lib/Basic/TargetInfo.cpp | 2 +- clang/lib/Lex/TextEncoding.cpp | 2 +- clang/lib/Sema/SemaStmtAsm.cpp | 10 ++++++---- clang/test/CodeGen/systemz-charset.c | 4 ++++ 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index dba50e03cc6d6..0518e8beb5a68 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -330,7 +330,7 @@ class TargetInfo : public TransferrableTargetInfo, virtual ~TargetInfo(); - std::unique_ptr<llvm::TextEncodingConverter> TargetStrConverter; + std::unique_ptr<llvm::TextEncodingConverter> FromSystemEncodingConverter; /// Retrieve the target options. TargetOptions &getTargetOpts() const { diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 1cc49cf84ce4c..3cecb1adc6511 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -199,7 +199,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { MaxBitIntWidth.reset(); - TargetStrConverter = nullptr; + FromSystemEncodingConverter = nullptr; } // Out of line virtual dtor for TargetInfo. diff --git a/clang/lib/Lex/TextEncoding.cpp b/clang/lib/Lex/TextEncoding.cpp index effd05185faf7..fd59f3df59bdf 100644 --- a/clang/lib/Lex/TextEncoding.cpp +++ b/clang/lib/Lex/TextEncoding.cpp @@ -62,7 +62,7 @@ TextEncoding::setConvertersFromOptions(TextEncoding &TE, TInfo.getDefaultOrdinaryLiteralEncoding(), UTF8); if (ErrorOrConverter) - TInfo.TargetStrConverter = + TInfo.FromSystemEncodingConverter = std::make_unique<TextEncodingConverter>(std::move(*ErrorOrConverter)); else return ErrorOrConverter.getError(); diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index f1aab455b4411..8b61228db3533 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -245,13 +245,15 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) { Diag(Expr->getBeginLoc(), diag::err_asm_operand_empty_string) << SL->getSourceRange(); } - if (Context.getTargetInfo().TargetStrConverter) { + if (Context.getTargetInfo().FromSystemEncodingConverter) { SmallString<16> ConvertedAsm; - Context.getTargetInfo().TargetStrConverter->convert(SL->getString(), - ConvertedAsm); + Context.getTargetInfo().FromSystemEncodingConverter->convert( + SL->getString(), ConvertedAsm); + QualType StrTy = Context.getStringLiteralArrayType(Context.CharTy, + ConvertedAsm.size()); return StringLiteral::Create(Context, ConvertedAsm, StringLiteralKind::Ordinary, - /*Pascal*/ false, {}, SL->getBeginLoc()); + /*Pascal*/ false, StrTy, SL->getBeginLoc()); } return SL; } diff --git a/clang/test/CodeGen/systemz-charset.c b/clang/test/CodeGen/systemz-charset.c index f3bb1055ddf5e..4ccc9934e4bde 100644 --- a/clang/test/CodeGen/systemz-charset.c +++ b/clang/test/CodeGen/systemz-charset.c @@ -71,3 +71,7 @@ void asm_labeled_fn(void) __asm__("\174asm_sym"); void asm_labeled_fn(void) {} //CHECK: define{{.*}}void @"@asm_sym"( //CHECK-UTF8: define{{.*}}void @"@asm_sym"( + +void asm_stmt_fn(void) { __asm__("\225\226\227nop"); } +//CHECK: call void asm{{.*}}"nopnop" +//CHECK-UTF8: call void asm{{.*}}"nopnop" >From 2931a8a2d84dabc94e20619d69aedbfe54f4989f Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Fri, 17 Jul 2026 14:31:50 -0400 Subject: [PATCH 05/10] check for UTF-8 to avoid conversion codepath if no conversion is needed --- clang/lib/Sema/SemaStmtAsm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 8b61228db3533..e0c3f7c7fd84f 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -245,7 +245,7 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) { Diag(Expr->getBeginLoc(), diag::err_asm_operand_empty_string) << SL->getSourceRange(); } - if (Context.getTargetInfo().FromSystemEncodingConverter) { + if (Context.getTargetInfo().FromSystemEncodingConverter != nullptr) { SmallString<16> ConvertedAsm; Context.getTargetInfo().FromSystemEncodingConverter->convert( SL->getString(), ConvertedAsm); >From a18b6d5603ff9c0c1badb2e3a068d9197daa6f5a Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Tue, 11 Aug 2026 09:02:17 -0400 Subject: [PATCH 06/10] Remove unrelated testcases --- clang/test/CodeGen/systemz-charset-diag.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/clang/test/CodeGen/systemz-charset-diag.cpp b/clang/test/CodeGen/systemz-charset-diag.cpp index ad08e1f391214..4ed94810150a3 100644 --- a/clang/test/CodeGen/systemz-charset-diag.cpp +++ b/clang/test/CodeGen/systemz-charset-diag.cpp @@ -1,11 +1,3 @@ // RUN: %clang_cc1 -triple s390x-none-zos -fexec-charset IBM-1047 %s -std=c++17 -emit-llvm -o - -verify const char* Computer = "🖥️"; // expected-error-re {{conversion to literal encoding failed: {{.*}}}} - -static_assert(false, "Error string"); // expected-error {{static assertion failed: Error string}} - -[[deprecated("message")]] void test_deprecated() {return;} // expected-note {{'test_deprecated' has been explicitly marked deprecated here}} - -int main() { - test_deprecated(); // expected-warning {{'test_deprecated' is deprecated: message}} -} >From 509257d1de4c50bfc9ea350aee21a3d9c544ab76 Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Thu, 13 Aug 2026 14:18:12 -0400 Subject: [PATCH 07/10] constexpr in asm strings will be in fexec-charset, do not do backwards conversion for those strings --- clang/include/clang/Sema/Sema.h | 3 ++- clang/lib/Parse/Parser.cpp | 5 ++++- clang/lib/Sema/SemaStmtAsm.cpp | 7 +++++-- clang/test/CodeGen/systemz-charset.cpp | 24 ++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 8ff9cba3ead47..de87529aa9d9f 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11429,7 +11429,8 @@ class Sema final : public SemaBase { ///@{ public: - ExprResult ActOnGCCAsmStmtString(Expr *Stm, bool ForAsmLabel); + ExprResult ActOnGCCAsmStmtString(Expr *Stm, bool ForAsmLabel, + bool IsConstExpr = false); StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, IdentifierInfo **Names, diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index d6856206d900b..6d1e006a180de 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1554,6 +1554,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) { ExprResult AsmString; + bool IsConstExpr = false; if (isTokenStringLiteral()) { AsmString = ParseStringLiteralExpression(/*AllowUserDefinedLiteral=*/false, /*Unevaluated=*/false, @@ -1569,6 +1570,7 @@ ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) { } } else if (!ForAsmLabel && getLangOpts().CPlusPlus11 && Tok.is(tok::l_paren)) { + IsConstExpr = true; ParenParseOption ExprType = ParenParseOption::SimpleExpr; SourceLocation RParenLoc; ParsedType CastTy; @@ -1588,7 +1590,8 @@ ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) { (getLangOpts().CPlusPlus11 && !ForAsmLabel) ? 0 : 1); } - return Actions.ActOnGCCAsmStmtString(AsmString.get(), ForAsmLabel); + return Actions.ActOnGCCAsmStmtString(AsmString.get(), ForAsmLabel, + IsConstExpr); } ExprResult Parser::ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc) { diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index e0c3f7c7fd84f..a4506587f3675 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -235,7 +235,8 @@ getClobberConflictLocation(MultiExprArg Exprs, Expr **Constraints, return SourceLocation(); } -ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) { +ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel, + bool IsConstExpr) { if (!Expr) return ExprError(); @@ -245,7 +246,8 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) { Diag(Expr->getBeginLoc(), diag::err_asm_operand_empty_string) << SL->getSourceRange(); } - if (Context.getTargetInfo().FromSystemEncodingConverter != nullptr) { + if (!IsConstExpr && + Context.getTargetInfo().FromSystemEncodingConverter != nullptr) { SmallString<16> ConvertedAsm; Context.getTargetInfo().FromSystemEncodingConverter->convert( SL->getString(), ConvertedAsm); @@ -272,6 +274,7 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) { ConstantExpr *Res = ConstantExpr::Create(getASTContext(), Expr, ConstantResultStorageKind::APValue); + Res->SetResult(V, getASTContext()); return Res; } diff --git a/clang/test/CodeGen/systemz-charset.cpp b/clang/test/CodeGen/systemz-charset.cpp index 41674e9c11a64..6348fb72dac9a 100644 --- a/clang/test/CodeGen/systemz-charset.cpp +++ b/clang/test/CodeGen/systemz-charset.cpp @@ -72,3 +72,27 @@ const char16_t *UnicodeUCNString16 = u"\u00E2\u00AC\U000000DF"; const char32_t *UnicodeUCNString32 = U"\u00E2\u00AC\U000000DF"; //CHECK: [4 x i32] [i32 226, i32 172, i32 223, i32 0] //CHECK-UTF8: [4 x i32] [i32 226, i32 172, i32 223, i32 0] + + +struct string_view { + int S; + const char* D; + constexpr string_view() : S(0), D(0){} + constexpr string_view(const char* Str) : S(__builtin_strlen(Str)), D(Str) {} + constexpr string_view(int Size, const char* Str) : S(Size), D(Str) {} + constexpr int size() const { + return S; + } + constexpr const char* data() const { + return D; + } +}; + +constexpr string_view getfoo() { return "\174foo"; } + +void function() +{ + asm((getfoo())); +} +// CHECK: asm{{.*}}|\86\96\96 +// CHECK-UTF8: asm{{.*}}|foo >From 61b1af4f9ab8f89615a57abcd8202fc8178890ed Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Wed, 30 Sep 2026 11:52:59 -0400 Subject: [PATCH 08/10] rename FromSystemEncodingConverter and move out of TargetInfo --- clang/include/clang/Basic/TargetInfo.h | 3 --- clang/include/clang/Lex/TextEncoding.h | 14 +++++++++++++- clang/lib/Basic/TargetInfo.cpp | 2 -- clang/lib/Lex/TextEncoding.cpp | 19 +++++++++++++------ clang/lib/Sema/SemaStmtAsm.cpp | 9 +++++---- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 0518e8beb5a68..6311b6b567a5e 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -38,7 +38,6 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Error.h" -#include "llvm/Support/TextEncoding.h" #include "llvm/Support/VersionTuple.h" #include "llvm/TargetParser/Triple.h" #include <cassert> @@ -330,8 +329,6 @@ class TargetInfo : public TransferrableTargetInfo, virtual ~TargetInfo(); - std::unique_ptr<llvm::TextEncodingConverter> FromSystemEncodingConverter; - /// Retrieve the target options. TargetOptions &getTargetOpts() const { assert(TargetOpts && "Missing target options"); diff --git a/clang/include/clang/Lex/TextEncoding.h b/clang/include/clang/Lex/TextEncoding.h index 02cb16cef9f1b..ec826ec661592 100644 --- a/clang/include/clang/Lex/TextEncoding.h +++ b/clang/include/clang/Lex/TextEncoding.h @@ -27,10 +27,22 @@ enum ConversionAction { class TextEncoding { llvm::StringRef LiteralEncoding; std::unique_ptr<llvm::TextEncodingConverter> ToLiteralEncodingConverter; - std::unique_ptr<llvm::TextEncodingConverter> ToSystemEncodingConverter; + + // Only non-null on z/OS, where the system default encoding is IBM-1047. + // This converts UTF-8 to IBM-1047 for asm string literals so that + // octal/hex escape sequences are interpreted as IBM-1047 code points, + // regardless of -fexec-charset. + std::unique_ptr<llvm::TextEncodingConverter> ToIBM1047Converter; + std::unique_ptr<llvm::TextEncodingConverter> FromIBM1047Converter; public: llvm::TextEncodingConverter *getConverter(ConversionAction Action) const; + + /// Returns the converter from IBM-1047 to UTF-8, or nullptr if not on z/OS. + llvm::TextEncodingConverter *getFromIBM1047Converter() const { + return FromIBM1047Converter.get(); + } + static std::error_code setConvertersFromOptions(TextEncoding &TE, const clang::LangOptions &Opts, clang::TargetInfo &TInfo); diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 3cecb1adc6511..1bb0026d8422e 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -198,8 +198,6 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { MaxOpenCLWorkGroupSize = 1024; MaxBitIntWidth.reset(); - - FromSystemEncodingConverter = nullptr; } // Out of line virtual dtor for TargetInfo. diff --git a/clang/lib/Lex/TextEncoding.cpp b/clang/lib/Lex/TextEncoding.cpp index fd59f3df59bdf..6ee6f8a0ef266 100644 --- a/clang/lib/Lex/TextEncoding.cpp +++ b/clang/lib/Lex/TextEncoding.cpp @@ -18,7 +18,8 @@ TextEncoding::getConverter(ConversionAction Action) const { case CA_ToLiteralEncoding: return ToLiteralEncodingConverter.get(); case CA_ToSystemEncoding: - return ToSystemEncodingConverter.get(); + // return null for non-z/OS targets + return ToIBM1047Converter.get(); default: return nullptr; } @@ -34,6 +35,8 @@ TextEncoding::setConvertersFromOptions(TextEncoding &TE, TE.LiteralEncoding = Opts.LiteralEncoding.empty() ? UTF8 : Opts.LiteralEncoding.c_str(); + // Create converter between internal and literal encoding specified + // in fexec-charset option. if (TE.LiteralEncoding != UTF8) { ErrorOr<TextEncodingConverter> ErrorOrLiteralConverter = llvm::TextEncodingConverter::create(UTF8, TE.LiteralEncoding); @@ -47,22 +50,26 @@ TextEncoding::setConvertersFromOptions(TextEncoding &TE, if (TInfo.getDefaultOrdinaryLiteralEncoding() == UTF8) return std::error_code(); - // Create converter between internal and default ordinary encoding for the - // target + // The IBM-1047 converters are only needed on z/OS, where the system + // (assembler/linker) default encoding is IBM-1047 rather than UTF-8. + assert((TInfo.getTriple().getOS() == llvm::Triple::ZOS) && + "Non-UTF-8 system encoding is only expected on z/OS"); + + // Create a converter from UTF-8 to IBM-1047 for use when parsing asm string + // literals on z/OS, where escape sequences are IBM-1047 code points. ErrorOr<TextEncodingConverter> ErrorOrConverter = llvm::TextEncodingConverter::create( UTF8, TInfo.getDefaultOrdinaryLiteralEncoding()); if (ErrorOrConverter) - TE.ToSystemEncodingConverter = + TE.ToIBM1047Converter = std::make_unique<TextEncodingConverter>(std::move(*ErrorOrConverter)); else return ErrorOrConverter.getError(); ErrorOrConverter = llvm::TextEncodingConverter::create( TInfo.getDefaultOrdinaryLiteralEncoding(), UTF8); - if (ErrorOrConverter) - TInfo.FromSystemEncodingConverter = + TE.FromIBM1047Converter = std::make_unique<TextEncodingConverter>(std::move(*ErrorOrConverter)); else return ErrorOrConverter.getError(); diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index a4506587f3675..f8c5e904effb7 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -15,6 +15,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/TextEncoding.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Ownership.h" @@ -24,6 +25,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" #include "llvm/MC/MCParser/MCAsmParser.h" +#include "llvm/Support/TextEncoding.h" #include <optional> using namespace clang; using namespace sema; @@ -247,10 +249,10 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel, << SL->getSourceRange(); } if (!IsConstExpr && - Context.getTargetInfo().FromSystemEncodingConverter != nullptr) { + PP.getTextEncoding().getFromIBM1047Converter() != nullptr) { SmallString<16> ConvertedAsm; - Context.getTargetInfo().FromSystemEncodingConverter->convert( - SL->getString(), ConvertedAsm); + PP.getTextEncoding().getFromIBM1047Converter()->convert(SL->getString(), + ConvertedAsm); QualType StrTy = Context.getStringLiteralArrayType(Context.CharTy, ConvertedAsm.size()); return StringLiteral::Create(Context, ConvertedAsm, @@ -274,7 +276,6 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel, ConstantExpr *Res = ConstantExpr::Create(getASTContext(), Expr, ConstantResultStorageKind::APValue); - Res->SetResult(V, getASTContext()); return Res; } >From 8951bc8e0407db1bf460394636c10b0a3a6b8d0f Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Mon, 5 Oct 2026 10:13:37 -0400 Subject: [PATCH 09/10] rename CA_ToSystemEncoding to CA_ToLiteralEncodingForAsm --- clang/include/clang/Lex/TextEncoding.h | 2 +- clang/lib/Lex/TextEncoding.cpp | 2 +- clang/lib/Parse/Parser.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Lex/TextEncoding.h b/clang/include/clang/Lex/TextEncoding.h index ec826ec661592..46903a5361059 100644 --- a/clang/include/clang/Lex/TextEncoding.h +++ b/clang/include/clang/Lex/TextEncoding.h @@ -20,7 +20,7 @@ class TextEncodingConverter; namespace clang { enum ConversionAction { CA_NoConversion, - CA_ToSystemEncoding, + CA_ToLiteralEncodingForAsm, // IBM-1047 on z/OS, UTF-8 on other platforms CA_ToLiteralEncoding }; diff --git a/clang/lib/Lex/TextEncoding.cpp b/clang/lib/Lex/TextEncoding.cpp index 6ee6f8a0ef266..afb5130ece88e 100644 --- a/clang/lib/Lex/TextEncoding.cpp +++ b/clang/lib/Lex/TextEncoding.cpp @@ -17,7 +17,7 @@ TextEncoding::getConverter(ConversionAction Action) const { switch (Action) { case CA_ToLiteralEncoding: return ToLiteralEncodingConverter.get(); - case CA_ToSystemEncoding: + case CA_ToLiteralEncodingForAsm: // return null for non-z/OS targets return ToIBM1047Converter.get(); default: diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 6d1e006a180de..afebe64d3e66d 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1558,7 +1558,7 @@ ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) { if (isTokenStringLiteral()) { AsmString = ParseStringLiteralExpression(/*AllowUserDefinedLiteral=*/false, /*Unevaluated=*/false, - CA_ToSystemEncoding); + CA_ToLiteralEncodingForAsm); if (AsmString.isInvalid()) return AsmString; >From bcd956509f05849dec71f136867ee78376f570b0 Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Wed, 7 Oct 2026 10:56:26 -0400 Subject: [PATCH 10/10] add more testcases, make diagnostic message generic --- clang/include/clang/Basic/DiagnosticLexKinds.td | 2 +- clang/test/CodeGen/systemz-charset-diag.cpp | 2 +- clang/test/CodeGen/systemz-charset.cpp | 8 ++++++-- clang/test/Sema/systemz-charset-asm.cpp | 11 +++++++++++ 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 clang/test/Sema/systemz-charset-asm.cpp diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index f0791ed486a74..bc1518b7995b7 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -292,7 +292,7 @@ def ext_string_too_long : Extension<"string literal of length %0 exceeds " def err_character_too_large : Error< "character too large for enclosing character literal type">; def err_exec_charset_conversion_failed - : Error<"conversion to literal encoding failed: '%0'">; + : Error<"encoding conversion failed: '%0'">; def warn_c99_compat_unicode_literal : Warning< "unicode literals are incompatible with C99">, InGroup<C99Compat>, DefaultIgnore; diff --git a/clang/test/CodeGen/systemz-charset-diag.cpp b/clang/test/CodeGen/systemz-charset-diag.cpp index 4ed94810150a3..a59a5ef4f0604 100644 --- a/clang/test/CodeGen/systemz-charset-diag.cpp +++ b/clang/test/CodeGen/systemz-charset-diag.cpp @@ -1,3 +1,3 @@ // RUN: %clang_cc1 -triple s390x-none-zos -fexec-charset IBM-1047 %s -std=c++17 -emit-llvm -o - -verify -const char* Computer = "🖥️"; // expected-error-re {{conversion to literal encoding failed: {{.*}}}} +const char* Computer = "🖥️"; // expected-error-re {{encoding conversion failed: {{.*}}}} diff --git a/clang/test/CodeGen/systemz-charset.cpp b/clang/test/CodeGen/systemz-charset.cpp index 6348fb72dac9a..b6b79842468c1 100644 --- a/clang/test/CodeGen/systemz-charset.cpp +++ b/clang/test/CodeGen/systemz-charset.cpp @@ -92,7 +92,11 @@ constexpr string_view getfoo() { return "\174foo"; } void function() { + asm("\174foo"); + // CHECK: asm{{.*}}@foo + // CHECK-UTF8: asm{{.*}}@foo asm((getfoo())); + // CHECK: asm{{.*}}|\86\96\96 + // CHECK-UTF8: asm{{.*}}|foo } -// CHECK: asm{{.*}}|\86\96\96 -// CHECK-UTF8: asm{{.*}}|foo + diff --git a/clang/test/Sema/systemz-charset-asm.cpp b/clang/test/Sema/systemz-charset-asm.cpp new file mode 100644 index 0000000000000..b3c27cc53638e --- /dev/null +++ b/clang/test/Sema/systemz-charset-asm.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple s390x-none-zos -fexec-charset IBM-1047 %s -std=c++23 -fsyntax-only -verify +// RUN: %clang_cc1 -triple s390x-none-zos -fexec-charset UTF-8 %s -std=c++23 -fsyntax-only -verify + +long inline_asm_ucn_named_operand(long a, long b) { + // The \N{...} escape encodes to U+0130. IBM-1047 has no code point for + // U+0130, so the conversion reports an error. + asm("\tLGR %0, %[\N{LATIN CAPITAL LETTER I WITH DOT ABOVE}]\n" // expected-error-re {{encoding conversion failed: {{.*}}}} + : "=r"(a) + : [\N{LATIN CAPITAL LETTER I WITH DOT ABOVE}] "r"(b)); + return a; +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
