diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 15d63e8e9459..7b2b87bdf4fd 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -149,9 +149,17 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy { return mlir::cir::ConstPtrAttr::get(getContext(), t, v); } - mlir::cir::ConstArrayAttr getString(llvm::StringRef str, mlir::Type eltTy, - unsigned size = 0) { + mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, + unsigned size = 0) { unsigned finalSize = size ? size : str.size(); + + // If the string is full of null bytes, emit a #cir.zero rather than + // a #cir.const_array. + if (str.count('\0') == str.size()) { + auto arrayTy = mlir::cir::ArrayType::get(getContext(), eltTy, finalSize); + return getZeroAttr(arrayTy); + } + auto arrayTy = mlir::cir::ArrayType::get(getContext(), eltTy, finalSize); return getConstArray(mlir::StringAttr::get(str, arrayTy), arrayTy); } diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index 3962c1f9f026..0c2989fe00e6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -1395,7 +1395,12 @@ mlir::cir::GlobalOp CIRGenItaniumRTTIBuilder::GetAddrOfTypeName( auto Align = CGM.getASTContext().getTypeAlignInChars(CGM.getASTContext().CharTy); - auto GV = CGM.createOrReplaceCXXRuntimeVariable(loc, Name, Init.getType(), + // builder.getString can return a #cir.zero if the string given to it only + // contains null bytes. However, type names cannot be full of null bytes. + // So cast Init to a ConstArrayAttr should be safe. + auto InitStr = cast(Init); + + auto GV = CGM.createOrReplaceCXXRuntimeVariable(loc, Name, InitStr.getType(), Linkage, Align); CIRGenModule::setInitializer(GV, Init); return GV; diff --git a/clang/test/CIR/CodeGen/globals.c b/clang/test/CIR/CodeGen/globals.c index ca347f425df6..522687aac53f 100644 --- a/clang/test/CIR/CodeGen/globals.c +++ b/clang/test/CIR/CodeGen/globals.c @@ -41,7 +41,7 @@ struct { char y[3]; char z[3]; } nestedString = {"1", "", "\0"}; -// CHECK: cir.global external @nestedString = #cir.const_struct<{#cir.const_array<"1\00\00" : !cir.array> : !cir.array, #cir.const_array<"\00\00\00" : !cir.array> : !cir.array, #cir.const_array<"\00\00\00" : !cir.array> : !cir.array}> +// CHECK: cir.global external @nestedString = #cir.const_struct<{#cir.const_array<"1\00\00" : !cir.array> : !cir.array, #cir.zero : !cir.array, #cir.zero : !cir.array}> struct { char *name;