diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 7038655bc94..551d004c241 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -2535,13 +2535,13 @@ public: { /* Copy the string contents to a null terminated string. */ dinteger_t length = (e->len * e->sz); - char *string = XALLOCAVEC (char, length + 1); + char *string = XALLOCAVEC (char, length + e->sz); + memset (string, 0, length + e->sz); if (length > 0) memcpy (string, e->string, length); - string[length] = '\0'; /* String value and type includes the null terminator. */ - tree value = build_string (length, string); + tree value = build_string (length + e->sz, string); TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1); value = build_address (value); diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc index f2180d30546..8d6c8f0f9ad 100644 --- a/gcc/d/modules.cc +++ b/gcc/d/modules.cc @@ -277,12 +277,13 @@ get_compiler_dso_type (void) DECL_CHAIN (field) = fields; fields = field; - field = create_field_decl (build_pointer_type (get_moduleinfo_type ()), - NULL, 1, 1); + tree moduleinfo_ptr_ptr_type = + build_pointer_type (build_pointer_type (get_moduleinfo_type ())); + + field = create_field_decl (moduleinfo_ptr_ptr_type, NULL, 1, 1); DECL_CHAIN (field) = fields; fields = field; - field = create_field_decl (build_pointer_type (get_moduleinfo_type ()), - NULL, 1, 1); + field = create_field_decl (moduleinfo_ptr_ptr_type, NULL, 1, 1); DECL_CHAIN (field) = fields; fields = field; diff --git a/gcc/testsuite/gdc.dg/analyzer/analyzer.exp b/gcc/testsuite/gdc.dg/analyzer/analyzer.exp new file mode 100644 index 00000000000..7b82b8e0cd1 --- /dev/null +++ b/gcc/testsuite/gdc.dg/analyzer/analyzer.exp @@ -0,0 +1,51 @@ +# Copyright (C) 2023 Free Software Foundation, Inc. + +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3, or (at your option) any later +# version. +# +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gdc-dg.exp + +# If the analyzer has not been enabled, bail. +if { ![check_effective_target_analyzer] } { + return +} + +global DEFAULT_DFLAGS +if [info exists DEFAULT_DFLAGS] then { + set save_default_dflags $DEFAULT_DFLAGS +} + +# If a testcase doesn't have special options, use these. +set DEFAULT_DFLAGS "-fanalyzer -Wanalyzer-too-complex -fanalyzer-call-summaries" + +# Initialize `dg'. +dg-init + +# Main loop. +gdc-dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/*.d ] ] "" $DEFAULT_DFLAGS + +# All done. +dg-finish + +if [info exists save_default_dflags] { + set DEFAULT_DFLAGS $save_default_dflags +} else { + unset DEFAULT_DFLAGS +} diff --git a/gcc/testsuite/gdc.dg/analyzer/pr111537.d b/gcc/testsuite/gdc.dg/analyzer/pr111537.d new file mode 100644 index 00000000000..e50b05a3f79 --- /dev/null +++ b/gcc/testsuite/gdc.dg/analyzer/pr111537.d @@ -0,0 +1,7 @@ +// { dg-do compile } +import core.stdc.string; +void main() +{ + char[5] arr; + strcpy(arr.ptr, "hello world"); // { dg-warning "stack-based buffer overflow" } +}