diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp index cfda6e8ded760..8860bcc54a9c1 100644 --- a/clang/lib/AST/ByteCode/Context.cpp +++ b/clang/lib/AST/ByteCode/Context.cpp @@ -245,6 +245,9 @@ bool Context::evaluateStrlen(State &Parent, const Expr *E, uint64_t &Result) { if (!FieldDesc->isPrimitiveArray()) return false; + if (Ptr.isDummy() || Ptr.isUnknownSizeArray()) + return false; + unsigned N = Ptr.getNumElems(); if (Ptr.elemSize() == 1) { Result = strnlen(reinterpret_cast(Ptr.getRawAddress()), N); diff --git a/clang/test/AST/ByteCode/strlen-unknown-size-array.cpp b/clang/test/AST/ByteCode/strlen-unknown-size-array.cpp new file mode 100644 index 0000000000000..ddc857009f57d --- /dev/null +++ b/clang/test/AST/ByteCode/strlen-unknown-size-array.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter %s -verify +// RUN: %clang_cc1 -std=c++20 %s -verify=ref + +// expected-no-diagnostics +// ref-no-diagnostics + +/// Test that __builtin_strlen() on external/unknown declarations doesn't crash the bytecode interpreter. +extern const char s[]; +void foo(char *x) +{ + unsigned long len = __builtin_strlen(s); + __builtin_strcpy(x, s); +}