diff options
author | Ian Lance Taylor <iant@golang.org> | 2020-12-04 14:51:32 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-12-04 14:51:32 -0800 |
commit | 945ae3ab27757d3261d99446f96105c5ebe70247 (patch) | |
tree | a8a120ef5393206d3bc9d2b5882bac1562824836 /gcc/testsuite | |
parent | f012991e2db06cc95f7aac8ecb74a1ac5f51f3d2 (diff) | |
parent | 918a5b84a2c51dc9d011d39461cc276e6558069d (diff) | |
download | gcc-945ae3ab27757d3261d99446f96105c5ebe70247.zip gcc-945ae3ab27757d3261d99446f96105c5ebe70247.tar.gz gcc-945ae3ab27757d3261d99446f96105c5ebe70247.tar.bz2 |
Merge from trunk revision 918a5b84a2c51dc9d011d39461cc276e6558069d
Diffstat (limited to 'gcc/testsuite')
39 files changed, 2169 insertions, 39 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3339d70..0e91a06 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,148 @@ +2020-12-03 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp2a/concepts-nodiscard1.C: XFAIL. + +2020-12-03 Martin Sebor <msebor@redhat.com> + + PR c++/90629 + PR middle-end/94527 + * g++.dg/asan/asan_test.cc: Fix a bug. + * g++.dg/warn/delete-array-1.C: Add expected warning. + * g++.old-deja/g++.other/delete2.C: Add expected warning. + * g++.dg/warn/Wfree-nonheap-object-2.C: New test. + * g++.dg/warn/Wfree-nonheap-object.C: New test. + * g++.dg/warn/Wmismatched-new-delete.C: New test. + * g++.dg/warn/Wmismatched-dealloc-2.C: New test. + * g++.dg/warn/Wmismatched-dealloc.C: New test. + * gcc.dg/Wmismatched-dealloc.c: New test. + * gcc.dg/analyzer/malloc-1.c: Prune out expected warning. + * gcc.dg/attr-malloc.c: New test. + * gcc.dg/free-1.c: Adjust text of expected warning. + * gcc.dg/free-2.c: Same. + * gcc.dg/torture/pr71816.c: Prune out expected warning. + * gcc.dg/tree-ssa/pr19831-2.c: Add an expected warning. + * gcc.dg/Wfree-nonheap-object-2.c: New test. + * gcc.dg/Wfree-nonheap-object-3.c: New test. + * gcc.dg/Wfree-nonheap-object.c: New test. + * g++.dg/warn/Wfree-nonheap-object.s: New file. + +2020-12-03 Harald Anlauf <anlauf@gmx.de> + + PR fortran/95342 + * gfortran.dg/pr95342.f90: New test. + +2020-12-03 Ian Lance Taylor <iant@golang.org> + + * go.test/go-test.exp (go-gc-tests): Add -I. when building all + sources in a directory (errorcheckdir, compiledir, rundir, + rundircmpout). + +2020-12-03 Jason Merrill <jason@redhat.com> + + PR c++/98019 + * g++.dg/cpp2a/concepts-nodiscard1.C: New test. + +2020-12-03 Uroš Bizjak <ubizjak@gmail.com> + Jakub Jelinek <jakub@redhat.com> + + PR target/98086 + * gcc.target/i386/pr98086.c: New test. + +2020-12-03 Nathan Sidwell <nathan@acm.org> + + PR c++/98115 + PR c++/98116 + * g++.dg/template/pr98115.C: New. + * g++.dg/template/pr98116.C: New. + +2020-12-03 Andreas Krebbel <krebbel@linux.ibm.com> + + * gcc.target/s390/stack-clash-4.c: New test. + +2020-12-03 Richard Sandiford <richard.sandiford@arm.com> + + * gcc.target/aarch64/sve/acle/general/undef_1.c: New test. + +2020-12-03 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.dg/pr98099.c: New test. + +2020-12-03 Eric Botcazou <ebotcazou@adacore.com> + + * g++.dg/cpp2a/pr98082.C: New test. + +2020-12-03 Jakub Jelinek <jakub@redhat.com> + + PR libstdc++/93121 + * g++.dg/cpp2a/bit-cast1.C: New test. + * g++.dg/cpp2a/bit-cast2.C: New test. + * g++.dg/cpp2a/bit-cast3.C: New test. + * g++.dg/cpp2a/bit-cast4.C: New test. + * g++.dg/cpp2a/bit-cast5.C: New test. + +2020-12-03 Jakub Jelinek <jakub@redhat.com> + + * g++.dg/cpp2a/consteval-defarg2.C: New test. + +2020-12-03 Jakub Jelinek <jakub@redhat.com> + + PR c++/98104 + * g++.dg/warn/pr98104.C: New test. + +2020-12-03 liuhongt <hongtao.liu@intel.com> + + * gcc.target/i386/avx512bw-pr96906-1.c: New test. + * gcc.target/i386/pr96906-1.c: Add -mno-avx512f. + +2020-12-03 liuhongt <hongtao.liu@intel.com> + + * gcc.target/i386/avx512bw-vmovdqu16-1.c: Adjust testcase to + make sure only masked load instruction is generated. + * gcc.target/i386/avx512bw-vmovdqu8-1.c: Ditto. + * gcc.target/i386/avx512f-vmovapd-1.c: Ditto. + * gcc.target/i386/avx512f-vmovaps-1.c: Ditto. + * gcc.target/i386/avx512f-vmovdqa32-1.c: Ditto. + * gcc.target/i386/avx512f-vmovdqa64-1.c: Ditto. + * gcc.target/i386/avx512vl-vmovapd-1.c: Ditto. + * gcc.target/i386/avx512vl-vmovaps-1.c: Ditto. + * gcc.target/i386/avx512vl-vmovdqa32-1.c: Ditto. + * gcc.target/i386/avx512vl-vmovdqa64-1.c: Ditto. + * gcc.target/i386/pr97642-1.c: New test. + * gcc.target/i386/pr97642-2.c: New test. + +2020-12-03 Jason Merrill <jason@redhat.com> + + * g++.dg/parse/defarg17.C: New test. + +2020-12-03 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp2a/consteval-defarg1.C: New test. + +2020-12-03 Hongyu Wang <hongyu.wang@intel.com> + + PR target/97770 + * gcc.target/i386/avx512bitalg-pr97770-1.c: New test. + * gcc.target/i386/avx512vpopcntdq-pr97770-1.c: Likewise. + * gcc.target/i386/avx512vpopcntdq-pr97770-2.c: Likewise. + * gcc.target/i386/avx512vpopcntdqvl-pr97770-1.c: Likewise. + +2020-12-03 Alexandre Oliva <oliva@adacore.com> + + * lib/options.exp (check_for_options_with_filter): Detect + unavailable compiler for the selected language, and bail out + as unsupported. + +2020-12-03 Martin Sebor <msebor@redhat.com> + + * gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Adjust expected warnings + to correctly reflect the maximum object size. + * gcc.dg/tree-ssa/builtin-sprintf-warn-11.c: Same. + * gcc.dg/tree-ssa/builtin-sprintf-warn-18.c: Same. + +2020-12-03 Ilya Leoshkevich <iii@linux.ibm.com> + + * gcc.target/s390/builtin-constant-p-threading.c: New test. + 2020-12-03 Peter Bergner <bergner@linux.ibm.com> PR c++/97947 diff --git a/gcc/testsuite/g++.dg/asan/asan_test.cc b/gcc/testsuite/g++.dg/asan/asan_test.cc index 5f2e2c2..dbf1a6a 100644 --- a/gcc/testsuite/g++.dg/asan/asan_test.cc +++ b/gcc/testsuite/g++.dg/asan/asan_test.cc @@ -829,7 +829,7 @@ NOINLINE static int LargeFunction(bool do_bad_access) { x[18]++; x[19]++; - delete x; + delete[] x; return res; } diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast6.C b/gcc/testsuite/g++.dg/cpp2a/bit-cast6.C new file mode 100644 index 0000000..4b70da1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast6.C @@ -0,0 +1,31 @@ +// PR libstd++/93121 +// { dg-do compile { target c++20 } } + +namespace std +{ +enum class byte : unsigned char {}; +template <typename To, typename From> +constexpr To +bit_cast (const From &from) +{ + return __builtin_bit_cast (To, from); +} +} + +struct S { unsigned short s[2]; }; +constexpr std::byte from1[sizeof (S)]{}; +constexpr auto to1 = std::bit_cast<S>(from1); +constexpr unsigned char from2[sizeof (S)]{}; +constexpr auto to2 = std::bit_cast<S>(from2); + +constexpr bool +cmp (const S &s1, const S &s2) +{ + for (int i = 0; i < sizeof (s1.s) / sizeof (s1.s[0]); i++) + if (s1.s[i] != s2.s[i]) + return false; + return true; +} + +static_assert (cmp (to1, S{})); +static_assert (cmp (to2, S{})); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-nodiscard1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-nodiscard1.C index 28ce29b..907e68b 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-nodiscard1.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-nodiscard1.C @@ -1,5 +1,6 @@ // PR c++/98019 // { dg-do compile { target c++20 } } +// { dg-excess-errors *-*-* } template <class T, class U> concept same_as = __is_same_as (T, U); diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class40.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class40.C new file mode 100644 index 0000000..d193544 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class40.C @@ -0,0 +1,79 @@ +// PR c++/93083 +// { dg-do compile { target c++20 } } + +template<unsigned N> +struct FixedString +{ + char buf[N + 1]{}; + constexpr FixedString(char const* s) { + for (unsigned i = 0; i != N; ++i) buf[i] = s[i]; + } + + auto operator<=>(const FixedString&) const = default; + constexpr operator char const*() const { return buf; } + constexpr static unsigned size() noexcept { return N; } +}; + +template<unsigned N> FixedString(char const (&)[N]) -> FixedString<N - 1>; + +template <FixedString... names> +struct name_list +{ + template <FixedString name> + using add_name = name_list< + names..., + FixedString<name.size()>{ name } + >; +}; + + +int main() +{ + using names = + name_list<> + ::add_name<"Zaphod Beeblebrox">; + +} + +// ---------------- + +template <int N> struct literal { + constexpr literal(const char (&input)[N]) noexcept { } + constexpr literal(const literal &) noexcept { } +}; + +template <literal Name, int id> struct field { }; + +template <literal Name> struct field<Name, 1u> { }; + +// ---------------- + +template <int N> +struct use_as_nttp {}; + +template <use_as_nttp Value> +struct has_nttp {}; + +template <use_as_nttp Value> +using has_nttp_2 = has_nttp<Value>; + +// ---------------- + +using size_t = decltype(sizeof(0)); + +template <size_t N> +struct string_literal +{ + constexpr string_literal(const char*) {} + string_literal(string_literal const&) = default; +}; +template <size_t N> +string_literal(const char (&)[N]) -> string_literal<N - 1>; + +template <string_literal Str> +struct type_string { }; + +template <string_literal Str> +void foo() { + type_string<Str>{}; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/srcloc1.C b/gcc/testsuite/g++.dg/cpp2a/srcloc1.C index 6e19ff7..029a037 100644 --- a/gcc/testsuite/g++.dg/cpp2a/srcloc1.C +++ b/gcc/testsuite/g++.dg/cpp2a/srcloc1.C @@ -88,7 +88,7 @@ quux () const char *file1 = source_location::current ().file_name (); const char *file2 = __FILE__; const char *function1 = source_location::current ().function_name (); - const char *function2 = __FUNCTION__; + const char *function2 = __PRETTY_FUNCTION__; int line1 = source_location::current ().line (); int line2 = __LINE__ - 1; int column diff --git a/gcc/testsuite/g++.dg/cpp2a/srcloc15.C b/gcc/testsuite/g++.dg/cpp2a/srcloc15.C index 30e5845..d02617e 100644 --- a/gcc/testsuite/g++.dg/cpp2a/srcloc15.C +++ b/gcc/testsuite/g++.dg/cpp2a/srcloc15.C @@ -44,12 +44,12 @@ struct S { source_location loc = source_location::current (); constexpr S (int l, source_location loc = source_location::current ()) - : func(__FUNCTION__), line(l), loc(loc) + : func(__PRETTY_FUNCTION__), line(l), loc(loc) {} constexpr S (double) - : func(__FUNCTION__), line(__LINE__) - // ^ column 38 + : func(__PRETTY_FUNCTION__), line(__LINE__) + // ^ column 45 {} }; @@ -73,7 +73,7 @@ bar () // ^ column 49 const source_location *d[3] = { &a, &b, &c }; const char *file1 = __FILE__; - const char *function1 = __FUNCTION__; + const char *function1 = __PRETTY_FUNCTION__; for (int j = 0; j < 3; j++) { int i= 0; @@ -104,7 +104,7 @@ bar () return false; if (e.loc.column () != 9) return false; - if (f.loc.column () != 38) + if (f.loc.column () != 45) return false; return true; } diff --git a/gcc/testsuite/g++.dg/cpp2a/srcloc17.C b/gcc/testsuite/g++.dg/cpp2a/srcloc17.C index 16704d0..a02ea48 100644 --- a/gcc/testsuite/g++.dg/cpp2a/srcloc17.C +++ b/gcc/testsuite/g++.dg/cpp2a/srcloc17.C @@ -46,12 +46,12 @@ struct S { source_location loc = source_location::current (); constexpr S (int l, source_location loc = source_location::current ()) - : func(__FUNCTION__), line(l), loc(loc) + : func(__PRETTY_FUNCTION__), line(l), loc(loc) {} constexpr S (double) - : func(__FUNCTION__), line(__LINE__) - // ^ column 38 + : func(__PRETTY_FUNCTION__), line(__LINE__) + // ^ column 45 {} }; @@ -76,7 +76,7 @@ bar () // ^ column 48 const source_location *d[3] = { &a, &b, &c }; const char *file1 = __FILE__; - const char *function1 = b.function_name (); + const char *function1 = __PRETTY_FUNCTION__; for (int j = 0; j < 3; j++) { int i= 0; @@ -107,7 +107,7 @@ bar () return false; if (e.loc.column () != 8) return false; - if (f.loc.column () != 38) + if (f.loc.column () != 45) return false; return true; } diff --git a/gcc/testsuite/g++.dg/cpp2a/srcloc2.C b/gcc/testsuite/g++.dg/cpp2a/srcloc2.C index 5ef09bb..4e0b960 100644 --- a/gcc/testsuite/g++.dg/cpp2a/srcloc2.C +++ b/gcc/testsuite/g++.dg/cpp2a/srcloc2.C @@ -92,7 +92,7 @@ quux () const char *file1 = source_location::current ().file_name (); const char *file2 = __FILE__; const char *function1 = source_location::current ().function_name (); - const char *function2 = __FUNCTION__; + const char *function2 = __PRETTY_FUNCTION__; int line1 = source_location::current ().line (); int line2 = __LINE__ - 1; int column diff --git a/gcc/testsuite/g++.dg/opt/pr98130.C b/gcc/testsuite/g++.dg/opt/pr98130.C new file mode 100644 index 0000000..0af55ef --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr98130.C @@ -0,0 +1,25 @@ +// PR c++/98130 +// { dg-do run { target c++11 } } +// { dg-options "-O2" } + +#include <new> + +typedef int *T; + +static unsigned char storage[sizeof (T)] alignas (T); +static T *p = (T *) storage; + +static inline __attribute__((__always_inline__)) void +foo (T value) +{ + new (p) T(value); +} + +int +main () +{ + int a; + foo (&a); + if (!*p) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/template/pr98116.C b/gcc/testsuite/g++.dg/template/pr98116.C index d3398d2..874c590 100644 --- a/gcc/testsuite/g++.dg/template/pr98116.C +++ b/gcc/testsuite/g++.dg/template/pr98116.C @@ -1,5 +1,11 @@ // PR 98116, ICE with stripping typedef array type // { dg-do compile { target c++11 } } +// { dg-additional-options {--param=hash-table-verification-limit=10000000 -fchecking=2} } +// { dg-ice "spec_hasher::equal" } + +// We get confused by alias templates that alias the same type. +// { dg-prune-output "hash table checking failed" } + namespace std { struct is_convertible; template <typename _Tp> using remove_pointer_t = typename _Tp ::type; diff --git a/gcc/testsuite/g++.dg/warn/Wfree-nonheap-object-2.C b/gcc/testsuite/g++.dg/warn/Wfree-nonheap-object-2.C new file mode 100644 index 0000000..9d4d2a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wfree-nonheap-object-2.C @@ -0,0 +1,274 @@ +/* PR ????? - No warning on attempts to access free object + Verify that freeing unallocated objects referenced either directly + or through pointers is diagnosed. + { dg-do compile } + { dg-options "-O2 -Wall -Wfree-nonheap-object" } */ + +typedef __INTPTR_TYPE__ intptr_t; +typedef __SIZE_TYPE__ size_t; + +extern "C" +{ + void free (void*); + extern void* malloc (size_t); + extern void* realloc (void *p, size_t); +} + +void sink (void*, ...); +#define sink(...) sink (0, __VA_ARGS__) + +extern char ecarr[]; +extern void* eparr[]; + +extern char *eptr; + +void* source (void); + +void nowarn_free (void *p, void **pp, size_t n, intptr_t iptr) +{ + free (p); + + p = 0; + free (p); + + p = malloc (n); + sink (p); + free (p); + + p = malloc (n); + sink (p); + + p = realloc (p, n * 2); + sink (p); + free (p); + + free ((void*)iptr); + + p = source (); + free (p); + + p = source (); + p = (char*)p - 1; + free (p); + + free (*pp); +} + +void warn_free_extern_arr (void) +{ + free (ecarr); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +void warn_free_extern_arr_offset (int i) +{ + char *p = ecarr + i; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +void warn_free_cstint (void) +{ + void *p = (void*)1; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +void warn_free_func (void) +{ + void *p = (void*)warn_free_func; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +void warn_free_string (int i) +{ + { + char *p = (char*)"123"; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + { + char *p = (char*)"234" + 1; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + { + char *p = (char*)"345" + i; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + + if (i >= 0) + { + char *p = (char*)"456" + i; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } +} + +void warn_free_local_arr (int i) +{ + { + char a[4]; + sink (a); + free (a); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + { + char b[5]; + sink (b); + + char *p = b + 1; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + { + char c[6]; + sink (c); + + char *p = c + i; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } +} + + +void warn_free_vla (int n, int i) +{ + { + int vla[n], *p = vla; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + + { + int vla[n + 1], *p = vla + 1; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + { + int vla[n + 2], *p = vla + i; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } +} + + +void nowarn_free_extern_ptrarr (void) +{ + free (*eparr); +} + +void nowarn_free_extern_ptrarr_offset (int i) +{ + void *p = eparr[i]; + free (p); +} + + +void warn_free_extern_ptrarr (void) +{ + free (eparr); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +void warn_free_extern_ptrarr_offset (int i) +{ + void *p = &eparr[i]; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +void nowarn_free_local_ptrarr (int i) +{ + void* a[4]; + sink (a); + free (a[0]); + free (a[1]); + free (a[i]); +} + + +void nowarn_free_extern_ptr (void) +{ + free (eptr); +} + +void nowarn_free_extern_ptr_offset (int i) +{ + char *p = eptr + i; + free (p); +} + +void warn_free_extern_ptr_pos_offset (int i) +{ + if (i <= 0) + i = 1; + + char *q = eptr + i; + free (q); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +void nowarn_free_parm_offset (char *p, int i) +{ + char *q = p + i; + free (q); +} + +void nowarn_free_parm_neg_offset (char *p, int i) +{ + if (i >= 0) + i = -1; + + char *q = p + i; + free (q); +} + +void warn_free_parm_pos_offset (char *p, int i) +{ + if (i <= 0) + i = 1; + + char *q = p + i; + free (q); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +struct Members +{ + char a[4], *p, *q; +}; + +extern struct Members em; + +void nowarn_free_member_ptr (struct Members *pm, int i) +{ + char *p = em.p; + free (p); + p = em.q + i; + free (p); + + free (pm->q); + p = pm->p; + free (pm); + free (p); +} + +void nowarn_free_struct_cast (intptr_t *p) +{ + struct Members *q = (struct Members*)*p; + if (q->p == 0) + free (q); // { dg-bogus "\\\[-Wfree-nonheap-object" } +} + + +void warn_free_member_array (void) +{ + char *p = em.a; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +void warn_free_member_array_off (int i) +{ + char *p = em.a + i; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} diff --git a/gcc/testsuite/g++.dg/warn/Wfree-nonheap-object.C b/gcc/testsuite/g++.dg/warn/Wfree-nonheap-object.C new file mode 100644 index 0000000..82b081a --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wfree-nonheap-object.C @@ -0,0 +1,124 @@ +/* PR ????? - No warning on attempts to access free object + Verify that attempts to deallocate objects by pointers with nonzero + offsets is diagnosed. + { dg-do compile } + { dg-options "-O2 -Wall -Wfree-nonheap-object" } */ + +typedef __INTPTR_TYPE__ intptr_t; +typedef __SIZE_TYPE__ size_t; + +void sink (void*, ...); + +extern char ecarr[]; +extern void* eparr[]; + +extern char *eptr; + +char* source (void); + +void nowarn_op_delete (void *p, void ***ppp, size_t n, intptr_t iptr) +{ + operator delete (p); + + p = 0; + operator delete (p); + + p = operator new (n); + sink (p); + operator delete (p); + + p = operator new (n); + sink (p); + + operator delete ((void*)iptr); + + p = source (); + operator delete (p); + + p = source (); + p = (char*)p - 1; + operator delete (p); + + operator delete (**ppp); + operator delete (*ppp); + operator delete (ppp); +} + +void warn_op_delete_cstaddr (void *p) +{ + operator delete (p); + p = (void*)~0; + operator delete (p); // { dg-warning "called on a pointer to an unallocated object" } */ +} + +void warn_op_delete_funcaddr () +{ + void *p = (void*)&warn_op_delete_funcaddr; + operator delete (p); // { dg-warning "called on unallocated object 'void warn_op_delete_funcaddr()" } */ +} + +void warn_op_delete_string (void *p) +{ + operator delete (p); + p = (void*)""; + operator delete (p); // { dg-warning "called on a pointer to an unallocated object" } */ +} + +void warn_op_delete_ptr_to_self (void *p) +{ + operator delete (p); + p = &p; + operator delete (p); // { dg-warning "called on unallocated object 'p'" } */ +} + +void nowarn_op_new_delete (size_t n) +{ + void *p = operator new (n); + sink (p); + operator delete (p); +} + +void nowarn_op_new_delete_ptr_plus (size_t n) +{ + void *p0_1 = operator new (n); + void *p1 = (char*)p0_1 + 1; + sink (p0_1, p1); + void *p0_2 = (char*)p1 - 1; + sink (p0_1, p1, p0_2); + operator delete (p0_2); +} + +void warn_op_new_delete_cstoff (size_t n) +{ + void *p = operator new (n); + void *q = (char*)p + 1; + sink (p, q); + operator delete (q); // { dg-warning "'void operator delete\\\(void\\\*\\\)' called on pointer '\[^'\]+' with nonzero offset 1" } +} + +void warn_op_new_delete_ptr_plus (size_t n) +{ + char *p = (char*)operator new (n); + sink (++p); + operator delete (p); // { dg-warning "called on pointer '\[^']+' with nonzero offset 1" } +} + +void warn_op_delete_funcret_plus (size_t n) +{ + char *p = source (); + sink (++p); + operator delete (p); // { dg-warning "called on pointer '\[^']+' with nonzero offset 1" } +} + +void warn_op_delete_eptr_plus (int i) +{ + extern char *ecp; + + if (i < 1) + i = 1; + + char *p = ecp + i; + sink (p); + + operator delete (p); // { dg-warning "called on pointer '\[^']+' with nonzero offset \\\[1, \\d+]" } +} diff --git a/gcc/testsuite/g++.dg/warn/Wfree-nonheap-object.s b/gcc/testsuite/g++.dg/warn/Wfree-nonheap-object.s new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wfree-nonheap-object.s diff --git a/gcc/testsuite/g++.dg/warn/Wmismatched-dealloc-2.C b/gcc/testsuite/g++.dg/warn/Wmismatched-dealloc-2.C new file mode 100644 index 0000000..7ecc99a --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wmismatched-dealloc-2.C @@ -0,0 +1,185 @@ +/* PR middle-end/94527 - Add an attribute that marks a function as freeing + an object + The detection doesn't require optimization. + { dg-do compile } + { dg-options "-Wall" } */ + +#define A(...) __attribute__ ((malloc (__VA_ARGS__))) + +typedef __SIZE_TYPE__ size_t; + +extern "C" { + void free (void *); + void* realloc (void *, size_t); +} + +void sink (void *); + +void mydealloc (int, void*); +void* A (mydealloc, 2) myalloc (void*); + + +void my_delete (const char*, void*); +void my_array_delete (const char*, void*); + +typedef void OpDelete1 (void*); +typedef void OpDelete2 (void*, size_t); + +A ((OpDelete1*)operator delete, 1) +#if __cplusplus >= 201402L +A ((OpDelete2*)operator delete, 1) +#endif +A (my_delete, 2) +int* my_new (size_t); + +A ((OpDelete1*)operator delete[], 1) +#if __cplusplus >= 201402L +A ((OpDelete2*)operator delete[], 1) +#endif +A (my_array_delete, 2) +int* my_array_new (size_t); + + +void test_my_new () +{ + { + void *p = my_new (1); + operator delete (p); + } + { + void *p = my_new (1); + sink (p); + operator delete (p); + } + { + int *p = my_new (1); + sink (p); + delete p; + } + + { + void *p = my_new (1); + // { dg-message "returned from a call to 'int\\\* my_new\\\(size_t\\\)'" "note" { target *-*-* } .-1 } + operator delete[] (p); + // { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function \\\[-Wmismatched-new-delete" "" { target *-*-* } .-1 } + } + { + void *p = my_new (1); + // { dg-message "returned from a call to 'int\\\* my_new\\\(size_t\\\)'" "note" { target *-*-* } .-1 } + sink (p); + operator delete[] (p); + // { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function \\\[-Wmismatched-new-delete" "" { target *-*-* } .-1 } + } + { + int *p = my_new (1); + sink (p); + delete[] p; + // { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function \\\[-Wmismatched-new-delete" "" { target *-*-* } .-1 } + } + + { + void *p = my_new (1); + my_delete ("1", p); + } + { + void *p = my_new (1); + sink (p); + my_delete ("2", p); + } + + { + void *p = my_new (1); + // { dg-message "returned from a call to 'int\\\* my_new\\\(size_t\\\)'" "note" { target *-*-* } .-1 } + sink (p); + my_array_delete ("3", p); + // { dg-warning "'void my_array_delete\\\(const char\\\*, void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } + + { + void *p = my_new (1); + // { dg-message "returned from a call to 'int\\\* my_new\\\(size_t\\\)'" "note" { target *-*-* } .-1 } + sink (p); + free (p); + // { dg-warning "'void free\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } + + { + void *p = my_new (1); + // { dg-message "returned from a call to 'int\\\* my_new\\\(size_t\\\)'" "note" { target *-*-* } .-1 } + sink (p); + p = realloc (p, 123); + // { dg-warning "'void\\\* realloc\\\(void\\\*, size_t\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } +} + + +void test_my_array_new () +{ + { + void *p = my_array_new (1); + operator delete[] (p); + } + { + void *p = my_array_new (1); + sink (p); + operator delete[] (p); + } + { + int *p = my_array_new (1); + sink (p); + delete[] p; + } + + { + void *p = my_array_new (1); + // { dg-message "returned from a call to 'int\\\* my_array_new\\\(size_t\\\)'" "note" { target *-*-* } .-1 } + operator delete (p); + // { dg-warning "'void operator delete\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function \\\[-Wmismatched-new-delete" "" { target *-*-* } .-1 } + } + { + void *p = my_array_new (1); + // { dg-message "returned from a call to 'int\\\* my_array_new\\\(size_t\\\)'" "note" { target *-*-* } .-1 } + sink (p); + operator delete (p); + // { dg-warning "'void operator delete\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function \\\[-Wmismatched-new-delete" "" { target *-*-* } .-1 } + } + { + int *p = my_array_new (1); + sink (p); + delete p; + // { dg-warning "'void operator delete\\\(void\\\*\[^\)\]*\\\)' called on pointer returned from a mismatched allocation function \\\[-Wmismatched-new-delete" "" { target *-*-* } .-1 } + } + + { + void *p = my_array_new (1); + my_array_delete ("1", p); + } + { + void *p = my_array_new (1); + sink (p); + my_array_delete ("2", p); + } + { + void *p = my_array_new (1); + // { dg-message "returned from a call to 'int\\\* my_array_new\\\(size_t\\\)'" "note" { target *-*-* } .-1 } + sink (p); + my_delete ("3", p); + // { dg-warning "'void my_delete\\\(const char\\\*, void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } + + { + void *p = my_array_new (1); + // { dg-message "returned from a call to 'int\\\* my_array_new\\\(size_t\\\)'" "note" { target *-*-* } .-1 } + sink (p); + free (p); + // { dg-warning "'void free\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } + + { + void *p = my_array_new (1); + // { dg-message "returned from a call to 'int\\\* my_array_new\\\(size_t\\\)'" "note" { target *-*-* } .-1 } + sink (p); + p = realloc (p, 123); + // { dg-warning "'void\\\* realloc\\\(void\\\*, size_t\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } +} diff --git a/gcc/testsuite/g++.dg/warn/Wmismatched-dealloc.C b/gcc/testsuite/g++.dg/warn/Wmismatched-dealloc.C new file mode 100644 index 0000000..682db6f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wmismatched-dealloc.C @@ -0,0 +1,27 @@ +/* PR middle-end/94527 - Add an attribute that marks a function as freeing + an object + { dg-do compile { target c++11 } } + { dg-options "-Wall" } */ + +#define A(...) __attribute__ ((malloc (__VA_ARGS__))) + +typedef __SIZE_TYPE__ size_t; + +void mydealloc (int, void*); +void* A (mydealloc, 2) myalloc (void*); + + +void* A (operator delete, 1) + bad_new (size_t); // { dg-error "attribute argument 1 is ambiguous" } +void* A (operator delete[], 1) + bad_array_new (size_t); // { dg-error "attribute argument 1 is ambiguous" } + +void my_delete (const char*, void*); +void my_array_delete (const char*, void*); + +typedef void OpDelete (void*); + +int* A ((OpDelete*)operator delete, 1) A (my_delete, 2) + my_new (size_t); +int* A ((OpDelete*)operator delete[], 1) A (my_array_delete, 2) + my_array_new (size_t); diff --git a/gcc/testsuite/g++.dg/warn/Wmismatched-new-delete.C b/gcc/testsuite/g++.dg/warn/Wmismatched-new-delete.C new file mode 100644 index 0000000..ed1090b --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wmismatched-new-delete.C @@ -0,0 +1,212 @@ +/* PR c++/90629 - Support for -Wmismatched-new-delete + The detection doesn't require optimization. + { dg-do compile } + { dg-options "-Wall" } */ + +typedef __SIZE_TYPE__ size_t; + +extern "C" { + void free (void *); + void* malloc (size_t); + void* realloc (void *, size_t); + char* strdup (const char *); + char* strndup (const char *, size_t); +} + +void sink (void *); + +void nowarn_op_new_delete (int n) +{ + void *p = operator new (n); + sink (p); + operator delete (p); +} + +void nowarn_new_delete (int n) +{ + { + char *p = new char; + sink (p); + delete p; + } + + { + char *p = new char[n]; + sink (p); + delete[] p; + } +} + +/* Verify a warning for calls to free() with a pointer returned from + a call to operator new() or the new expressopm. */ + +void warn_new_free (int n) +{ + { + void *p = operator new (n); + // { dg-message "returned from a call to 'void\\\* operator new\\\(" "note" { target *-*-* } .-1 } + sink (p); + free (p); + // { dg-warning "'void free\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } + { + char *p = new char[n]; + // { dg-message "returned from a call to 'void\\\* operator new \\\[" "note" { target *-*-* } .-1 } + sink (p); + free (p); + // { dg-warning "'void free\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } +} + + +/* Verify a warning for calls to realloc() with a pointer returned from + a call to operator new() or the new expressopm. */ + +void warn_new_realloc (int n) +{ + { + void *p = operator new (n); + // { dg-message "returned from a call to 'void\\\* operator new\\\(" "note" { target *-*-* } .-1 } + sink (p); + p = realloc (p, n * 2); + // { dg-warning "'void\\\* realloc\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + sink (p); + } + { + void *p = new char[n]; + // { dg-message "returned from a call to 'void\\\* operator new \\\[" "note" { target *-*-* } .-1 } + sink (p); + p = realloc (p, n * 2); + // { dg-warning "'void\\\* realloc\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + sink (p); + } +} + + +/* Verify a warning for a call to operator_delete() with a pointer returned + from a call to malloc(). */ + +void warn_malloc_op_delete (int n) +{ + char *p = (char *)malloc (n); + // { dg-message "returned from a call to 'void\\\* malloc\\\(" "note" { target *-*-* } .-1 } + sink (p); + operator delete (p); + // { dg-warning "'void operator delete\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } +} + + +/* Verify a warning for an invocation of either form of the delete + expression with a pointer returned from a call to malloc(). */ + +void warn_malloc_delete (int n) +{ + { + char *p = (char *)malloc (n); + // { dg-message "returned from a call to 'void\\\* malloc\\\(" "note" { target *-*-* } .-1 } + sink (p); + /* C++98 calls operator delete (void*) but later versions call + operator delete (void*, size_t). The difference doesn't matter + here so verify just that some operator delete is called. */ + delete p; + // { dg-warning "'void operator delete\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } + + { + char *p = (char *)malloc (n); + // { dg-message "returned from a call to 'void\\\* malloc\\\(" "note" { target *-*-* } .-1 } + sink (p); + delete[] p; + // { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } +} + + +/* Verify a warning for an invocation of either form of the delete + expression with a pointer returned from a call to realloc(). */ + +void warn_realloc_delete (void *p1, void *p2, int n) +{ + { + char *q = (char *)realloc (p1, n); + // { dg-message "returned from a call to 'void\\\* realloc\\\(" "note" { target *-*-* } .-1 } + sink (q); + /* C++98 calls operator delete (void*) but later versions call + operator delete (void*, size_t). The difference doesn't matter + here so verify just that some operator delete is called. */ + delete q; + // { dg-warning "'void operator delete\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } + + { + char *q = (char *)realloc (p2, n); + // { dg-message "returned from a call to 'void\\\* realloc\\\(" "note" { target *-*-* } .-1 } + sink (q); + delete[] q; + // { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } +} + + +/* Verify a warning for an invocation of either form of the delete + expression with a pointer returned from a call to strdup(). */ + +void warn_strdup_delete (const char *s1, const char *s2) +{ + { + char *q = strdup (s1); + // { dg-message "returned from a call to 'char\\\* strdup\\\(" "note" { target *-*-* } .-1 } + sink (q); + /* C++98 calls operator delete (void*) but later versions call + operator delete (void*, size_t). The difference doesn't matter + here so verify just that some operator delete is called. */ + delete q; + // { dg-warning "'void operator delete\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } + + { + char *q = strdup (s2); + // { dg-message "returned from a call to 'char\\\* strdup\\\(" "note" { target *-*-* } .-1 } + sink (q); + delete[] q; + // { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } +} + + + +/* Verify a warning for an invocation of either form of the delete + expression with a pointer returned from a call to strndup(). */ + +void warn_strdup_delete (const char *s1, const char *s2, size_t n) +{ + { + char *q = strndup (s1, n); + // { dg-message "returned from a call to 'char\\\* strndup\\\(" "note" { target *-*-* } .-1 } + sink (q); + /* C++98 calls operator delete (void*) but later versions call + operator delete (void*, size_t). The difference doesn't matter + here so verify just that some operator delete is called. */ + delete q; + // { dg-warning "'void operator delete\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } + + { + char *q = strndup (s2, n); + // { dg-message "returned from a call to 'char\\\* strndup\\\(" "note" { target *-*-* } .-1 } + sink (q); + delete[] q; + // { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 } + } +} + + +struct Base { virtual ~Base (); }; +struct Derived: Base { }; + +void warn_new_free_base_derived () +{ + Base *p = new Derived (); + sink (p); + free (p); // { dg-warning "\\\[-Wmismatched-new-delete" } +} diff --git a/gcc/testsuite/g++.dg/warn/delete-array-1.C b/gcc/testsuite/g++.dg/warn/delete-array-1.C index c3af713..95fa7d4 100644 --- a/gcc/testsuite/g++.dg/warn/delete-array-1.C +++ b/gcc/testsuite/g++.dg/warn/delete-array-1.C @@ -5,7 +5,7 @@ struct S { int a [1]; } s; void foo (S *p) { - delete a; // { dg-warning "deleting array" } - delete s.a; // { dg-warning "deleting array" } - delete p->a; // { dg-warning "deleting array" } + delete a; // { dg-warning "deleting array|-Wfree-nonheap-object" } + delete s.a; // { dg-warning "deleting array|-Wfree-nonheap-object" } + delete p->a; // { dg-warning "deleting array|-Wfree-nonheap-object" } } diff --git a/gcc/testsuite/g++.old-deja/g++.other/delete2.C b/gcc/testsuite/g++.old-deja/g++.other/delete2.C index 1d0554f..76ae355 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/delete2.C +++ b/gcc/testsuite/g++.old-deja/g++.other/delete2.C @@ -9,5 +9,7 @@ void bar(foo a) { delete[] a; // should be accepted char b[1]; delete b; // { dg-warning "deleting array" } expecting pointer type + // { dg-warning "-Wfree-nonheap-object" "" { target *-*-* } .-1 } delete[] b; // { dg-warning "deleting array" } expecting pointer type + // { dg-warning "-Wfree-nonheap-object" "" { target *-*-* } .-1 } } diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-2.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-2.c new file mode 100644 index 0000000..2b00d77 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-2.c @@ -0,0 +1,279 @@ +/* PR ????? - No warning on attempts to access free object + Verify that attempting to reallocate unallocated objects referenced + either directly or through pointers is diagnosed. + { dg-do compile } + { dg-options "-O2 -Wall -Wfree-nonheap-object" } */ + +typedef __SIZE_TYPE__ size_t; + +extern void free (void*); +extern void* alloca (size_t); +extern void* realloc (void*, size_t); + +void sink (void*, ...); + +extern void* eparr[]; +extern char *eptr; + +extern size_t n; + + +void nowarn_realloc (void *p, size_t n) +{ + char *q = realloc (p, n); + sink (q); + + q = realloc (0, n); + sink (q); + + q = realloc (q, n * 2); + sink (q); +} + +/* Verify that calling realloc on a pointer to an unknown object minus + some nonzero offset isn't diagnosed, but a pointer plus a positive + offset is (a positive offset cannot point at the beginning). */ + +void test_realloc_offset (char *p1, char *p2, char *p3, size_t n, int i) +{ + char *q; + q = realloc (p1 - 1, n); + sink (q); + + q = realloc (p2 + 1, n); // { dg-warning "'realloc' called on pointer 'p2' with nonzero offset 1" } + sink (q); + + q = realloc (p3 + i, n); + sink (q); +} + +void warn_realloc_extern_arr (void) +{ + extern char ecarr[]; // { gg-message "declared here" } + char *p = ecarr; + char *q = realloc (p, n); // { dg-warning "'realloc' called on unallocated object 'ecarr'" } + sink (q); +} + +void warn_realloc_extern_arr_offset (int i) +{ + extern char ecarr[]; + char *p = ecarr + i; + char *q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); +} + + +void warn_realloc_string (int i) +{ + char *p, *q; + { + p = "123"; + sink (p); + q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } + { + p = "234" + 1; + sink (p); + q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } + { + p = "123" + i; + sink (p); + q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } +} + + +void warn_realloc_alloca (int n, int i) +{ + char *p, *q; + { + p = alloca (n); + sink (p); + q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } + { + p = (char*)alloca (n + 1); + sink (p); + q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } + { + p = (char*)alloca (n + 2) + i; + sink (p); + q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } +} + + +void warn_realloc_local_arr (int i) +{ + char *q; + { + char a[4]; + sink (a); + q = realloc (a, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } + + { + char b[5]; + sink (b); + q = realloc (b + 1, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } + + { + char c[6]; + sink (c); + q = realloc (&c[2], n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } + + { + char d[7]; + sink (d); + q = realloc (&d[i], n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } +} + +void warn_realloc_vla (int n1, int n2, int i) +{ + char *q; + { + char vla[n1]; + sink (vla); + q = realloc (vla, n2); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } + + { + char vlb[n1 + 1]; + sink (vlb); + q = realloc (vlb + 1, n2);// { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } + + { + char vlc[n1 + 2]; + sink (vlc); + q = realloc (&vlc[2], n2);// { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } + + { + char vld[7]; + sink (vld); + q = realloc (&vld[i], n2);// { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); + } +} + +void nowarn_realloc_extern_ptrarr (void) +{ + char *q = realloc (*eparr, n); + sink (q); +} + +void nowarn_realloc_extern_ptrarr_offset (int i) +{ + char *p = eparr[i]; + char *q = realloc (p, n); + sink (q); +} + + +void warn_realloc_extern_ptrarr (void) +{ + char *q = realloc (eparr, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); +} + +void warn_realloc_extern_ptrarr_offset (int i) +{ + void *p = eparr + i; + void *q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); +} + + +void nowarn_realloc_extern_ptr (void) +{ + char *q = realloc (eptr, n); + sink (q); +} + +void nowarn_realloc_extern_ptr_offset (int i) +{ + char *p = eptr + i; + char *q = realloc (p, n); + sink (q); +} + + +void warn_realloc_extern_ptr_pos_offset (int i) +{ + if (i <= 0) + i = 1; + + char *p = eptr + i; + char *q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); +} + + +void nowarn_realloc_parm_offset (char *p, int i) +{ + char *q = p + i; + q = realloc (q, n); + sink (q); +} + +void nowarn_realloc_parm_neg_offset (char *p, int i) +{ + if (i >= 0) + i = -1; + + char *q = p + i; + q = realloc (q, n); + sink (q); +} + +void warn_realloc_parm_pos_offset (char *p, int i) +{ + if (i <= 0) + i = 1; + + char *q = p + i; + q = realloc (q, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); +} + +void nowarn_realloc_deref_parm_pos_offset (void **p, int i) +{ + if (i <= 0) + i = 1; + + // The offset is from p, not *p. + void *q = *(p + i); + q = realloc (q, n); + sink (q); +} + +void warn_realloc_deref_parm_pos_offset (void **p, int i) +{ + if (i <= 0) + i = 1; + + // Unlike in the function above the offset is from *p. + void *q = *p + i; + q = realloc (q, n); // { dg-warning "\\\[-Wfree-nonheap-object" } + sink (q); +} diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-3.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-3.c new file mode 100644 index 0000000..a472b93 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-3.c @@ -0,0 +1,57 @@ +/* PR ????? - No warning on attempts to access free object + Verify that freeing unallocated objects referenced indirectly through + pointers obtained from function calls is diagnosed. + { dg-do compile } + { dg-options "-O2 -Wall -Wfree-nonheap-object" } */ + +typedef __SIZE_TYPE__ size_t; + +extern void free (void*); +extern char* memchr (const void*, int, size_t); +extern char* strchr (const char*, int); + +void sink (void*, ...); + +extern char ecarr[]; +extern void* eparr[]; + +extern char *eptr; + + +void warn_free_memchr_ecarr (int x, size_t n) +{ + char *p = memchr (ecarr, x, n); + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +void warn_free_memchr_ecarr_offset (int i, int j, int x, size_t n) +{ + char *p = memchr (ecarr + i, x, n); + char *q = p + j; + sink (p, q); + free (q); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +void warn_free_memchr_local_arr (int x, size_t n) +{ + char a[8]; + sink (a); + + char *p = memchr (a, x, n); + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +void warn_free_memchr_local_arr_offset (int i, int j, int x, size_t n) +{ + char a[8]; + sink (a); + + char *p = memchr (a + i, x, n); + char *q = p + j; + sink (p, q); + free (q); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object.c new file mode 100644 index 0000000..bb222cc --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object.c @@ -0,0 +1,273 @@ +/* PR ????? - No warning on attempts to access free object + Verify that freeing unallocated objects referenced either directly + or through pointers is diagnosed. In most cases this doesn't require + optimization. + { dg-do compile } + { dg-options "-Wall -Wfree-nonheap-object" } */ + +typedef __INTPTR_TYPE__ intptr_t; +typedef __SIZE_TYPE__ size_t; + +extern void free (void*); +extern void* malloc (size_t); +extern void* realloc (void *p, size_t); + +void sink (void*, ...); + +extern char ecarr[]; +extern void* eparr[]; + +extern char *eptr; + +void* source (void); + +void nowarn_free (void *p, void **pp, size_t n, intptr_t iptr) +{ + free (p); + + p = 0; + free (p); + + p = malloc (n); + sink (p); + free (p); + + p = malloc (n); + sink (p); + + p = realloc (p, n * 2); + sink (p); + free (p); + + free ((void*)iptr); + + p = source (); + free (p); + + p = source (); + p = (char*)p - 1; + free (p); + + free (*pp); +} + +void warn_free_extern_arr (void) +{ + free (ecarr); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +void warn_free_extern_arr_offset (int i) +{ + char *p = ecarr + i; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +void warn_free_cstint (void) +{ + void *p = (void*)1; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +void warn_free_func (void) +{ + void *p = warn_free_func; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +void warn_free_string (int i) +{ + { + char *p = "123"; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + { + char *p = "234" + 1; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + { + char *p = "345" + i; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + + if (i >= 0) + { + char *p = "456" + i; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } +} + +void warn_free_local_arr (int i) +{ + { + char a[4]; + sink (a); + free (a); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + { + char b[5]; + sink (b); + + char *p = b + 1; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + { + char c[6]; + sink (c); + + char *p = c + i; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } +} + + +void warn_free_vla (int n, int i) +{ + { + int vla[n], *p = vla; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + + { + int vla[n + 1], *p = vla + 1; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } + { + int vla[n + 2], *p = vla + i; + sink (p); + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } + } +} + + +void nowarn_free_extern_ptrarr (void) +{ + free (*eparr); +} + +void nowarn_free_extern_ptrarr_offset (int i) +{ + char *p = eparr[i]; + free (p); +} + + +void warn_free_extern_ptrarr (void) +{ + free (eparr); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +void warn_free_extern_ptrarr_offset (int i) +{ + void *p = &eparr[i]; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +void nowarn_free_local_ptrarr (int i) +{ + void* a[4]; + sink (a); + free (a[0]); + free (a[1]); + free (a[i]); +} + + +void nowarn_free_extern_ptr (void) +{ + free (eptr); +} + +void nowarn_free_extern_ptr_offset (int i) +{ + char *p = eptr + i; + free (p); +} + +void nowarn_free_parm_offset (char *p, int i) +{ + char *q = p + i; + free (q); +} + +void nowarn_free_parm_neg_offset (char *p, int i) +{ + if (i >= 0) + i = -1; + + char *q = p + i; + free (q); +} + +struct Members +{ + char a[4], *p, *q; +}; + +extern struct Members em; + +void nowarn_free_member_ptr (struct Members *pm, int i) +{ + char *p = em.p; + free (p); + p = em.q + i; + free (p); + + free (pm->q); + p = pm->p; + free (pm); + free (p); +} + +void nowarn_free_struct_cast (intptr_t *p) +{ + struct Members *q = (struct Members*)*p; + if (q->p == 0) + free (q); // { dg-bogus "\\\[-Wfree-nonheap-object" } +} + + +void warn_free_member_array (void) +{ + char *p = em.a; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +void warn_free_member_array_off (int i) +{ + char *p = em.a + i; + free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + + +// Range information requires optimization. +#pragma GCC optimize "1" + +void warn_free_extern_ptr_pos_offset (int i) +{ + if (i <= 0) + i = 1; + + char *q = eptr + i; + free (q); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +void warn_free_parm_pos_offset (char *p, int i) +{ + if (i <= 0) + i = 1; + + char *q = p + i; + free (q); // { dg-warning "\\\[-Wfree-nonheap-object" } +} diff --git a/gcc/testsuite/gcc.dg/Wmismatched-dealloc.c b/gcc/testsuite/gcc.dg/Wmismatched-dealloc.c new file mode 100644 index 0000000..7c5d6ac --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wmismatched-dealloc.c @@ -0,0 +1,252 @@ +/* PR middle-end/94527 - Add an attribute that marks a function as freeing + an object + Verify that attribute malloc with one or two arguments has the expected + effect on diagnostics. + { dg-options "-Wall -ftrack-macro-expansion=0" } */ + +#define A(...) __attribute__ ((malloc (__VA_ARGS__))) + +typedef struct FILE FILE; +typedef __SIZE_TYPE__ size_t; + +void free (void*); +void* malloc (size_t); +void* realloc (void*, size_t); + +int fclose (FILE*); +FILE* freopen (const char*, const char*, FILE*); +int pclose (FILE*); + +A (fclose) A (freopen, 3) + FILE* fdopen (int); +A (fclose) A (freopen, 3) + FILE* fopen (const char*, const char*); +A (fclose) A (freopen, 3) + FILE* fmemopen(void *, size_t, const char *); +A (fclose) A (freopen, 3) + FILE* freopen (const char*, const char*, FILE*); +A (pclose) A (freopen, 3) + FILE* popen (const char*, const char*); +A (fclose) A (freopen, 3) + FILE* tmpfile (void); + +void sink (FILE*); + + + void release (void*); +A (release) FILE* acquire (void); + +void nowarn_fdopen (void) +{ + { + FILE *q = fdopen (0); + if (!q) + return; + + fclose (q); + } + + { + FILE *q = fdopen (0); + if (!q) + return; + + q = freopen ("1", "r", q); + fclose (q); + } + + { + FILE *q = fdopen (0); + if (!q) + return; + + sink (q); + } +} + + +void warn_fdopen (void) +{ + { + FILE *q = fdopen (0); // { dg-message "returned from a call to 'fdopen'" "note" } + sink (q); + release (q); // { dg-warning "'release' called on pointer returned from a mismatched allocation function" } + } + { + FILE *q = fdopen (0); // { dg-message "returned from a call to 'fdopen'" "note" } + sink (q); + free (q); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" } + } + + { + FILE *q = fdopen (0); // { dg-message "returned from a call to 'fdopen'" "note" } + sink (q); + q = realloc (q, 7); // { dg-warning "'realloc' called on pointer returned from a mismatched allocation function" } + sink (q); + } +} + + +void nowarn_fopen (void) +{ + { + FILE *q = fopen ("1", "r"); + sink (q); + fclose (q); + } + + { + FILE *q = fopen ("2", "r"); + sink (q); + q = freopen ("3", "r", q); + sink (q); + fclose (q); + } + + { + FILE *q = fopen ("4", "r"); + sink (q); + } +} + + +void warn_fopen (void) +{ + { + FILE *q = fopen ("1", "r"); + sink (q); + release (q); // { dg-warning "'release' called on pointer returned from a mismatched allocation function" } + } + { + FILE *q = fdopen (0); + sink (q); + free (q); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" } + } + + { + FILE *q = fdopen (0); + sink (q); + q = realloc (q, 7); // { dg-warning "'realloc' called on pointer returned from a mismatched allocation function" } + sink (q); + } +} + + +void test_popen (void) +{ + { + FILE *p = popen ("1", "r"); + sink (p); + pclose (p); + } + + { + FILE *p; + p = popen ("2", "r"); // { dg-message "returned from a call to 'popen'" "note" } + sink (p); + fclose (p); // { dg-warning "'fclose' called on pointer returned from a mismatched allocation function" } + } + + { + /* freopen() can close a stream open by popen() but pclose() can't + close the stream returned from freopen(). */ + FILE *p = popen ("2", "r"); + sink (p); + p = freopen ("3", "r", p); // { dg-message "returned from a call to 'freopen'" "note" } + sink (p); + pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" } + } +} + + +void test_tmpfile (void) +{ + { + FILE *p = tmpfile (); + sink (p); + fclose (p); + } + + { + FILE *p = tmpfile (); + sink (p); + p = freopen ("1", "r", p); + sink (p); + fclose (p); + } + + { + FILE *p = tmpfile (); // { dg-message "returned from a call to 'tmpfile'" "note" } + sink (p); + pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" } + } +} + + +void warn_malloc (void) +{ + { + FILE *p = malloc (100); // { dg-message "returned from a call to 'malloc'" "note" } + sink (p); + fclose (p); // { dg-warning "'fclose' called on pointer returned from a mismatched allocation function" } + } + + { + FILE *p = malloc (100); // { dg-message "returned from a call to 'malloc'" "note" } + sink (p); + p = freopen ("1", "r", p);// { dg-warning "'freopen' called on pointer returned from a mismatched allocation function" } + } + + { + FILE *p = malloc (100); // { dg-message "returned from a call to 'malloc'" "note" } + sink (p); + pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" } + } +} + + +void test_acquire (void) +{ + { + FILE *p = acquire (); + release (p); + } + + { + FILE *p = acquire (); + sink (p); + release (p); + } + + { + FILE *p = acquire (); // { dg-message "returned from a call to 'acquire'" "note" } + sink (p); + fclose (p); // { dg-warning "'fclose' called on pointer returned from a mismatched allocation function" } + } + + { + FILE *p = acquire (); // { dg-message "returned from a call to 'acquire'" "note" } + sink (p); + pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" } + } + + { + FILE *p = acquire (); // { dg-message "returned from a call to 'acquire'" "note" } + sink (p); + p = freopen ("1", "r", p); // { dg-warning "'freopen' called on pointer returned from a mismatched allocation function" } + sink (p); + } + + { + FILE *p = acquire (); // { dg-message "returned from a call to 'acquire'" "note" } + sink (p); + free (p); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" } + } + + { + FILE *p = acquire (); // { dg-message "returned from a call to 'acquire'" "note" } + sink (p); + p = realloc (p, 123); // { dg-warning "'realloc' called on pointer returned from a mismatched allocation function" } + sink (p); + } +} diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c index c5bf1227c..26d8288 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c @@ -609,3 +609,5 @@ int test_49 (int i) *p = 1; /* { dg-warning "dereference of NULL 'p' \\\[CWE-476\\\]" } */ return x; } + +/* { dg-prune-output "\\\[-Wfree-nonheap-object" } */ diff --git a/gcc/testsuite/gcc.dg/attr-malloc.c b/gcc/testsuite/gcc.dg/attr-malloc.c new file mode 100644 index 0000000..14f1980 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-malloc.c @@ -0,0 +1,75 @@ +/* PR middle-end/94527 - Add an attribute that marks a function as freeing + an object + Verify that attribute malloc with one or two arguments is accepted where + intended and rejected where it's invalid. + { dg-options "-Wall -ftrack-macro-expansion=0" } */ + +#define A(...) __attribute__ ((malloc (__VA_ARGS__))) + +A (0) void* alloc_zero (int); // { dg-error "'malloc' attribute argument 1 does not name a function" } + +A ("") void* alloc_string (int); // { dg-error "'malloc' attribute argument 1 does not name a function" } + +int var; +A (var) void* alloc_var (int); // { dg-error "'malloc' attribute argument 1 does not name a function" } + +typedef struct Type { int i; } Type; +A (Type) void* alloc_type (int); // { dg-error "expected expression|identifier" } + +A (unknown) void* alloc_unknown (int); // { dg-error "'unknown' undeclared" } + +void fv_ (); // { dg-message "declared here" } +A (fv_) void* alloc_fv_ (int); // { dg-error "'malloc' attribute argument 1 must take a pointer type as its first argument" } + +void fvi (int); // { dg-message "declared here" } +A (fvi) void* alloc_fvi (int); // { dg-error "'malloc' attribute argument 1 must take a pointer type as its first argument; have 'int'" } + +void fvv (void); // { dg-message "declared here" } +A (fvv) void* alloc_fvv (int); // { dg-error "'malloc' attribute argument 1 must take a pointer type as its first argument; have 'void'" } + +void fvi_ (int, ...); // { dg-message "declared here" } +A (fvi_) void* alloc_fvi_ (int); // { dg-error "'malloc' attribute argument 1 must take a pointer type as its first argument; have 'int'" } + +void fvi_vp (Type, void*); // { dg-message "declared here" } +A (fvi_vp) void* alloc_fvi_vp (int); // { dg-error "'malloc' attribute argument 1 must take a pointer type as its first argument; have 'Type'" } + + +void fpv (void*); +A (fpv) void* alloc_fpv (int); + +void fpv_i (void*, int); +A (fpv_i) void* alloc_fpv_i (int); + +void fpv_pv (void*, void*); +A (fpv_i) void* alloc_fpv_pv (int); + + +void gpc (char*); +void hpi (int*); +A (fpv) A (gpc) A (hpi) Type* alloc_fpv_gpv (int); + + +/* Verify that the attribute can be applied to <stdio.h> functions. */ +typedef struct FILE FILE; +typedef __SIZE_TYPE__ size_t; + +int fclose (FILE*); +FILE* fdopen (int); +FILE* fopen (const char*, const char*); +FILE* freopen (const char*, const char*, FILE*); +int pclose (FILE*); +FILE* popen (const char*, const char*); +FILE* tmpfile (void); + +A (fclose) A (freopen, 3) A (pclose) + FILE* fdopen (int); +A (fclose) A (freopen, 3) A (pclose) + FILE* fopen (const char*, const char*); +A (fclose) A (freopen, 3) A (pclose) + FILE* fmemopen(void *, size_t, const char *); +A (fclose) A (freopen, 3) A (pclose) + FILE* freopen (const char*, const char*, FILE*); +A (fclose) A (freopen, 3) A (pclose) + FILE* popen (const char*, const char*); +A (fclose) A (freopen, 3) A (pclose) + FILE* tmpfile (void); diff --git a/gcc/testsuite/gcc.dg/free-1.c b/gcc/testsuite/gcc.dg/free-1.c index 5496c84..ad49d78 100644 --- a/gcc/testsuite/gcc.dg/free-1.c +++ b/gcc/testsuite/gcc.dg/free-1.c @@ -13,14 +13,14 @@ void foo (void) static char buf4[10], e; char *q = buf; free (p); - free (q); /* { dg-warning "attempt to free a non-heap object" } */ - free (buf2); /* { dg-warning "attempt to free a non-heap object" } */ - free (&c); /* { dg-warning "attempt to free a non-heap object" } */ - free (buf3); /* { dg-warning "attempt to free a non-heap object" } */ - free (&d); /* { dg-warning "attempt to free a non-heap object" } */ - free (buf4); /* { dg-warning "attempt to free a non-heap object" } */ - free (&e); /* { dg-warning "attempt to free a non-heap object" } */ + free (q); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (buf2); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (&c); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (buf3); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (&d); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (buf4); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (&e); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ free (&r->a); - free ("abcd"); /* { dg-warning "attempt to free a non-heap object" } */ - free (L"abcd"); /* { dg-warning "attempt to free a non-heap object" } */ + free ("abcd"); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (L"abcd"); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ } diff --git a/gcc/testsuite/gcc.dg/free-2.c b/gcc/testsuite/gcc.dg/free-2.c index eb94651..edbcdc7 100644 --- a/gcc/testsuite/gcc.dg/free-2.c +++ b/gcc/testsuite/gcc.dg/free-2.c @@ -13,14 +13,14 @@ void foo (void) static char buf4[10], e; char *q = buf; free (p); - free (q); /* At -O0 no warning is reported here. */ - free (buf2); /* { dg-warning "attempt to free a non-heap object" } */ - free (&c); /* { dg-warning "attempt to free a non-heap object" } */ - free (buf3); /* { dg-warning "attempt to free a non-heap object" } */ - free (&d); /* { dg-warning "attempt to free a non-heap object" } */ - free (buf4); /* { dg-warning "attempt to free a non-heap object" } */ - free (&e); /* { dg-warning "attempt to free a non-heap object" } */ + free (q); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (buf2); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (&c); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (buf3); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (&d); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (buf4); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (&e); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ free (&r->a); - free ("abcd"); /* { dg-warning "attempt to free a non-heap object" } */ - free (L"abcd"); /* { dg-warning "attempt to free a non-heap object" } */ + free ("abcd"); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ + free (L"abcd"); /* { dg-warning "\\\[-Wfree-nonheap-object" } */ } diff --git a/gcc/testsuite/gcc.dg/pr98099.c b/gcc/testsuite/gcc.dg/pr98099.c index 34909f2..12e52f2 100644 --- a/gcc/testsuite/gcc.dg/pr98099.c +++ b/gcc/testsuite/gcc.dg/pr98099.c @@ -1,7 +1,7 @@ /* PR middle-end/98099 */ /* Reported by G. Steinmetz <gscfq@t-online.de> */ -/* { dg-do compile } */ +/* { dg-do compile { target dfp } } */ /* { dg-options "-fsso-struct=big-endian" } */ struct S { _Decimal128 a; }; diff --git a/gcc/testsuite/gcc.dg/torture/pr71816.c b/gcc/testsuite/gcc.dg/torture/pr71816.c index be37ad9..cc143fa 100644 --- a/gcc/testsuite/gcc.dg/torture/pr71816.c +++ b/gcc/testsuite/gcc.dg/torture/pr71816.c @@ -20,3 +20,7 @@ struct ext2_icount_el *insert_icount_el() { ext2fs_resize_mem(&insert_icount_el_icount_1); return 0; } + +/* Passing the address of a declared object to realloc triggers + -Wfree-nonheap-object unless -flto is used. + { dg-prune-output "\\\[-Wfree-nonheap-object" } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c index 6a03588..e6dd4be 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */ +/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized --param case-values-threshold=5" } */ int global; int foo (); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c index 464b1fb..b164067 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */ +/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized --param case-values-threshold=5" } */ int global; int foo (); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c index f43ce7d..f4d06fe 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */ +/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized --param case-values-threshold=5" } */ int global; int global1; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19831-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19831-2.c index 55b4fd0..df4120d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr19831-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr19831-2.c @@ -5,7 +5,7 @@ void test1(void) { int *p = __builtin_malloc (sizeof (int) * 4); *p++ = 4; - __builtin_free (p); + __builtin_free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } } /* Undefined. We can't do anything here. */ diff --git a/gcc/testsuite/gcc.target/i386/pr96226.c b/gcc/testsuite/gcc.target/i386/pr96226.c new file mode 100644 index 0000000..cc010fa --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr96226.c @@ -0,0 +1,16 @@ +/* PR target/96226 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "\troll\t" 4 } } */ +/* { dg-final { scan-assembler-times "\trolq\t" 4 { target { ! ia32 } } } } */ + +int f1 (int x) { return ~(1U << (x & 0x1f)); } +int f2 (int x) { return ~(1U << x); } +int f3 (unsigned char *x) { return ~(1U << (x[0] & 0x1f)); } +int f4 (unsigned char *x) { return ~(1U << x[0]); } +#ifdef __x86_64__ +long int f5 (int x) { return ~(1ULL << (x & 0x3f)); } +long int f6 (int x) { return ~(1ULL << x); } +long int f7 (unsigned char *x) { return ~(1ULL << (x[0] & 0x3f)); } +long int f8 (unsigned char *x) { return ~(1ULL << x[0]); } +#endif diff --git a/gcc/testsuite/gcc.target/i386/pr98100.c b/gcc/testsuite/gcc.target/i386/pr98100.c new file mode 100644 index 0000000..4deda1a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr98100.c @@ -0,0 +1,9 @@ +/* PR target/98100 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-avx -fvar-tracking-assignments -g0" } */ + +__attribute__((target_clones("default","avx2"))) void +foo () +{ + __attribute__((__vector_size__(8 * sizeof(int)))) int b = {}; +} diff --git a/gcc/testsuite/gnat.dg/opt91.adb b/gcc/testsuite/gnat.dg/opt91.adb new file mode 100644 index 0000000..b0132f8 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt91.adb @@ -0,0 +1,11 @@ +-- { dg-do compile } +-- { dg-options "-O2 -fchecking=1" } + +package body Opt91 is + + function Custom_Image (Self : True_Relation_Rec) return String is + begin + return "<True>"; + end; + +end Opt91; diff --git a/gcc/testsuite/gnat.dg/opt91.ads b/gcc/testsuite/gnat.dg/opt91.ads new file mode 100644 index 0000000..b31aa8d --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt91.ads @@ -0,0 +1,10 @@ +with Opt91_Pkg; use Opt91_Pkg; + +package Opt91 is + + type True_Relation_Rec is null record; + function Custom_Image (Self : True_Relation_Rec) return String; + + package True_Relation is new Pure_Relation (Ty => True_Relation_Rec); + +end Opt91; diff --git a/gcc/testsuite/gnat.dg/opt91_pkg.adb b/gcc/testsuite/gnat.dg/opt91_pkg.adb new file mode 100644 index 0000000..5b95fb2e --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt91_pkg.adb @@ -0,0 +1,12 @@ +package body Opt91_Pkg is + + package body Pure_Relation is + + overriding function Custom_Image (Self : Rel) return String is + begin + return Custom_Image (Self.Rel); + end Custom_Image; + + end Pure_Relation; + +end Opt91_Pkg; diff --git a/gcc/testsuite/gnat.dg/opt91_pkg.ads b/gcc/testsuite/gnat.dg/opt91_pkg.ads new file mode 100644 index 0000000..9bfd0f0 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt91_pkg.ads @@ -0,0 +1,19 @@ +package Opt91_Pkg is + + type Base_Relation is abstract tagged null record; + + function Custom_Image (Self : Base_Relation) return String is abstract; + + generic + type Ty is private; + with function Custom_Image (Self : Ty) return String is <>; + package Pure_Relation is + + type Rel is new Base_Relation with record + Rel : Ty; + end record; + + overriding function Custom_Image (Self : Rel) return String; + end Pure_Relation; + +end Opt91_Pkg; |