From 7122b70cfc8e23a069410215c363da76d842bda4 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva Date: Fri, 19 Jul 2024 14:24:05 +0200 Subject: [PATCH] [clang] Fix underlying type of EmbedExpr (#99050) This patch makes remaining cases of #embed to emit int type since there is an agreement to do that for C. C++ is being discussed, but in general we don't want to produce different types for C and C++. --- clang/lib/AST/Expr.cpp | 2 +- clang/lib/Sema/SemaInit.cpp | 2 +- clang/test/Preprocessor/Inputs/big_char.txt | 1 + clang/test/Preprocessor/embed_codegen.cpp | 8 ++++---- clang/test/Preprocessor/embed_weird.cpp | 11 +++++++++++ 5 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 clang/test/Preprocessor/Inputs/big_char.txt diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 6af1b5683e08bc..9d5b8167d0ee62 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2376,7 +2376,7 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx, EmbedExpr::EmbedExpr(const ASTContext &Ctx, SourceLocation Loc, EmbedDataStorage *Data, unsigned Begin, unsigned NumOfElements) - : Expr(EmbedExprClass, Ctx.UnsignedCharTy, VK_PRValue, OK_Ordinary), + : Expr(EmbedExprClass, Ctx.IntTy, VK_PRValue, OK_Ordinary), EmbedKeywordLoc(Loc), Ctx(&Ctx), Data(Data), Begin(Begin), NumOfElements(NumOfElements) { setDependence(ExprDependence::None); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 17435afab03f49..dc2ba039afe7f3 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -2016,7 +2016,7 @@ canInitializeArrayWithEmbedDataString(ArrayRef ExprList, if (InitType->isArrayType()) { const ArrayType *InitArrayType = InitType->getAsArrayTypeUnsafe(); QualType InitElementTy = InitArrayType->getElementType(); - QualType EmbedExprElementTy = EE->getType(); + QualType EmbedExprElementTy = EE->getDataStringLiteral()->getType(); const bool TypesMatch = Context.typesAreCompatible(InitElementTy, EmbedExprElementTy) || (InitElementTy->isCharType() && EmbedExprElementTy->isCharType()); diff --git a/clang/test/Preprocessor/Inputs/big_char.txt b/clang/test/Preprocessor/Inputs/big_char.txt new file mode 100644 index 00000000000000..ce542efaa5124a --- /dev/null +++ b/clang/test/Preprocessor/Inputs/big_char.txt @@ -0,0 +1 @@ +ÿ \ No newline at end of file diff --git a/clang/test/Preprocessor/embed_codegen.cpp b/clang/test/Preprocessor/embed_codegen.cpp index 2cf14d8d6a15d9..5baab9b59a9c16 100644 --- a/clang/test/Preprocessor/embed_codegen.cpp +++ b/clang/test/Preprocessor/embed_codegen.cpp @@ -14,9 +14,9 @@ int ca[] = { }; // CHECK: %arrayinit.element = getelementptr inbounds i32, ptr %notca, i64 1 -// CHECK: store i8 106, ptr %arrayinit.element, align 4 +// CHECK: store i32 106, ptr %arrayinit.element, align 4 // CHECK: %arrayinit.element1 = getelementptr inbounds i32, ptr %notca, i64 2 -// CHECK: store i8 107, ptr %arrayinit.element1, align 4 +// CHECK: store i32 107, ptr %arrayinit.element1, align 4 int notca[] = { a #embed prefix(,) @@ -75,9 +75,9 @@ constexpr struct T t[] = { // CHECK: %arrayinit.element7 = getelementptr inbounds %struct.T, ptr %tnonc, i64 1 // CHECK: call void @llvm.memset.p0.i64(ptr align 4 %arrayinit.element7, i8 0, i64 20, i1 false) // CHECK: %arr8 = getelementptr inbounds %struct.T, ptr %arrayinit.element7, i32 0, i32 0 -// CHECK: store i8 106, ptr %arr8, align 4 +// CHECK: store i32 106, ptr %arr8, align 4 // CHECK: %arrayinit.element9 = getelementptr inbounds i32, ptr %arr8, i64 1 -// CHECK: store i8 107, ptr %arrayinit.element9, align 4 +// CHECK: store i32 107, ptr %arrayinit.element9, align 4 struct T tnonc[] = { a, 300, 1, 2, 3 #embed prefix(,) diff --git a/clang/test/Preprocessor/embed_weird.cpp b/clang/test/Preprocessor/embed_weird.cpp index cc73a88e5a657b..6eb2923152f153 100644 --- a/clang/test/Preprocessor/embed_weird.cpp +++ b/clang/test/Preprocessor/embed_weird.cpp @@ -115,3 +115,14 @@ void f1() { }; } #endif + +struct HasChar { + signed char ch; +}; + +constexpr struct HasChar c = { +#embed "Inputs/big_char.txt" // cxx-error {{constant expression evaluates to 255 which cannot be narrowed to type 'signed char'}} \ + cxx-note {{insert an explicit cast to silence this issue}} \ + c-error {{constexpr initializer evaluates to 255 which is not exactly representable in type 'signed char'}} + +};