On Wed, Aug 3, 2011 at 2:31 PM, Jakub Jelinek <ja...@redhat.com> wrote:
> Hi!
>
> As mentioned in PR49905, -D_FORTIFY_SOURCE{,=2} handles e.g.
> malloc (4) or malloc (16) well, knowing that the resulting pointer
> has object size 4 resp. 16, but for new int or new int[4], it currently
> doesn't assume anything (i.e. __builtin_object_size (new int, 0) returns
> -1).  While I see the C++ standard unfortunately allows redefining
> of the new and vector new operators, I wonder if for -D_FORTIFY_SOURCE
> we could assume similar properties as for malloc for the object size
> checking, i.e. that if these two operators are called with a constant
> parameter, the object size allocated is the given size.  I hope there
> aren't C++ programs that override the default operator new, allocate fewer
> or more bytes and expect that those can be accessed through the pointer
> returned by new.  At least -D_FORTIFY_SOURCE=2 is declared to be stricter
> than the standard (but -D_FORTIFY_SOURCE=1 is not).  Of course this wouldn't
> affect programs not compiled with -D_FORTIFY_SOURCE{,=2}, wouldn't affect
> placement new nor any class operator new/new[] (unless it calls the default
> operator new/new[]).
>
> Comments?

If that's reasonable then adding the malloc attribute should be, too.
Finally.  Please.  Doesn't C++0x maybe "fix" the issue we were
discussing to death?

Richard.

> 2011-08-03  Jakub Jelinek  <ja...@redhat.com>
>
>        PR middle-end/49905
>        * decl.c (cxx_init_decl_processing): Add alloc_size (1) attribute
>        for operator new and operator new [].
>
>        * g++.dg/ext/builtin-object-size3.C: New test.
>
> --- gcc/cp/decl.c.jj    2011-07-22 22:14:59.000000000 +0200
> +++ gcc/cp/decl.c       2011-08-03 14:00:48.000000000 +0200
> @@ -3629,6 +3629,7 @@ cxx_init_decl_processing (void)
>   current_lang_name = lang_name_cplusplus;
>
>   {
> +    tree newattrs;
>     tree newtype, deltype;
>     tree ptr_ftype_sizetype;
>     tree new_eh_spec;
> @@ -3656,7 +3657,11 @@ cxx_init_decl_processing (void)
>     else
>       new_eh_spec = noexcept_false_spec;
>
> -    newtype = build_exception_variant (ptr_ftype_sizetype, new_eh_spec);
> +    newattrs
> +      = build_tree_list (get_identifier ("alloc_size"),
> +                        build_tree_list (NULL_TREE, integer_one_node));
> +    newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, newattrs);
> +    newtype = build_exception_variant (newtype, new_eh_spec);
>     deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
>     push_cp_library_fn (NEW_EXPR, newtype);
>     push_cp_library_fn (VEC_NEW_EXPR, newtype);
> --- gcc/testsuite/g++.dg/ext/builtin-object-size3.C.jj  2011-08-03 
> 14:06:03.000000000 +0200
> +++ gcc/testsuite/g++.dg/ext/builtin-object-size3.C     2011-08-03 
> 14:04:21.000000000 +0200
> @@ -0,0 +1,26 @@
> +// { dg-do compile }
> +// { dg-options "-O2" }
> +
> +void baz (int *, int *);
> +
> +#define MEMCPY(d,s,l) __builtin___memcpy_chk (d, s, l, __builtin_object_size 
> (d, 0))
> +
> +int
> +foo ()
> +{
> +  int *p = new int;
> +  int *q = new int[4];
> +  MEMCPY (p, "abcdefghijklmnopqrstuvwxyz", sizeof (int));
> +  MEMCPY (q, "abcdefghijklmnopqrstuvwxyz", 4 * sizeof (int));
> +  baz (p, q);
> +}
> +
> +int
> +bar ()
> +{
> +  int *p = new int;
> +  int *q = new int[4];
> +  MEMCPY (p, "abcdefghijklmnopqrstuvwxyz", sizeof (int) + 1);          // { 
> dg-warning "will always overflow destination buffer" }
> +  MEMCPY (q, "abcdefghijklmnopqrstuvwxyz", 4 * sizeof (int) + 1);      // { 
> dg-warning "will always overflow destination buffer" }
> +  baz (p, q);
> +}
>
>        Jakub
>

Reply via email to