[clang] 4909e7c - [clang][Interp] Zero-init remaining string literal elements (#66862)

via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 29 23:28:13 PDT 2023


Author: Timm Baeder
Date: 2023-09-30T08:28:09+02:00
New Revision: 4909e7cac7100ee0bc9ce755ffab114d320ac0e3

URL: https://github.com/llvm/llvm-project/commit/4909e7cac7100ee0bc9ce755ffab114d320ac0e3
DIFF: https://github.com/llvm/llvm-project/commit/4909e7cac7100ee0bc9ce755ffab114d320ac0e3.diff

LOG: [clang][Interp] Zero-init remaining string literal elements (#66862)

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/test/AST/Interp/arrays.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index a09e2a007b912c9..46906377863bd74 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -881,8 +881,8 @@ bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) {
 
   // If the initializer string is too long, a diagnostic has already been
   // emitted. Read only the array length from the string literal.
-  unsigned N =
-      std::min(unsigned(CAT->getSize().getZExtValue()), E->getLength());
+  unsigned ArraySize = CAT->getSize().getZExtValue();
+  unsigned N = std::min(ArraySize, E->getLength());
   size_t CharWidth = E->getCharByteWidth();
 
   for (unsigned I = 0; I != N; ++I) {
@@ -901,6 +901,23 @@ bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) {
       llvm_unreachable("unsupported character width");
     }
   }
+
+  // Fill up the rest of the char array with NUL bytes.
+  for (unsigned I = N; I != ArraySize; ++I) {
+    if (CharWidth == 1) {
+      this->emitConstSint8(0, E);
+      this->emitInitElemSint8(I, E);
+    } else if (CharWidth == 2) {
+      this->emitConstUint16(0, E);
+      this->emitInitElemUint16(I, E);
+    } else if (CharWidth == 4) {
+      this->emitConstUint32(0, E);
+      this->emitInitElemUint32(I, E);
+    } else {
+      llvm_unreachable("unsupported character width");
+    }
+  }
+
   return true;
 }
 

diff  --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp
index 7985f6841658e56..281835f828bbd7c 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -369,3 +369,24 @@ namespace ArrayInitLoop {
   static_assert(g() == 6); // expected-error {{failed}} \
                            // expected-note {{15 == 6}}
 }
+
+namespace StringZeroFill {
+  struct A {
+    char c[6];
+  };
+  constexpr A a = { "abc" };
+  static_assert(a.c[0] == 'a', "");
+  static_assert(a.c[1] == 'b', "");
+  static_assert(a.c[2] == 'c', "");
+  static_assert(a.c[3] == '\0', "");
+  static_assert(a.c[4] == '\0', "");
+  static_assert(a.c[5] == '\0', "");
+
+  constexpr char b[6] = "foo";
+  static_assert(b[0] == 'f', "");
+  static_assert(b[1] == 'o', "");
+  static_assert(b[2] == 'o', "");
+  static_assert(b[3] == '\0', "");
+  static_assert(b[4] == '\0', "");
+  static_assert(b[5] == '\0', "");
+}


        


More information about the cfe-commits mailing list