From b8d422830aa4478fc9e2affe1ac6026b05b350d4 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Sun, 11 Mar 2018 16:45:03 +0100 Subject: [PATCH] Fix Bug 285: Wrong codegen on optimized strlen() --- gcc/d/expr.cc | 29 ++++++++++++++++++++++------- gcc/testsuite/gdc.dg/runnable.d | 17 +++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index caf7267ca..92d885628 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -2593,24 +2593,39 @@ class ExprVisitor : public Visitor /* All strings are null terminated except static arrays. */ const char *string = (const char *)(e->len ? e->string : ""); - dinteger_t length = (e->len * e->sz); - tree value = build_string (length, string); tree type = build_ctype (e->type); if (tb->ty == Tsarray) - TREE_TYPE (value) = type; + { + /* Turn the string into a constructor for the static array. */ + vec *elms = NULL; + vec_safe_reserve (elms, e->len); + tree etype = TREE_TYPE (type); + + for (size_t i = 0; i < e->len; i++) + { + tree value = build_integer_cst (e->charAt (i), etype); + CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value); + } + + tree ctor = build_constructor (type, elms); + TREE_CONSTANT (ctor) = 1; + this->result_ = ctor; + } else { /* Array type string length includes the null terminator. */ - TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1); + dinteger_t length = (e->len * e->sz) + 1; + tree value = build_string (length, string); + TREE_TYPE (value) = make_array_type (tb->nextOf (), length); value = build_address (value); if (tb->ty == Tarray) value = d_array_value (type, size_int (e->len), value); - } - TREE_CONSTANT (value) = 1; - this->result_ = d_convert (type, value); + TREE_CONSTANT (value) = 1; + this->result_ = d_convert (type, value); + } } /* Build a tuple literal. Just an argument list that may have diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d index 82ec295bc..0a996046b 100644 --- a/gcc/testsuite/gdc.dg/runnable.d +++ b/gcc/testsuite/gdc.dg/runnable.d @@ -1531,6 +1531,22 @@ void test273() /******************************************/ +// Bug 285 + +inout(char)[] test285a(inout(char)* s) @nogc @system pure nothrow +{ + import core.stdc.string : strlen; + return s ? s[0 .. strlen(s)] : null; +} + +void test285() +{ + assert(test285a(null) == null); + assert(test285a("foo") == "foo"); +} + +/******************************************/ + void main() { test2(); @@ -1564,6 +1580,7 @@ void main() test248(); test250(); test273(); + test285(); printf("Success!\n"); }