Bug 55446 - [4.7/4.8 Regression] array new with size zero vanishes from object code
Summary: [4.7/4.8 Regression] array new with size zero vanishes from object code
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.2
: P3 normal
Target Milestone: 4.7.3
Assignee: Paolo Carlini
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2012-11-23 10:48 UTC by Jens Maurer
Modified: 2013-01-30 10:19 UTC (History)
2 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-11-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jens Maurer 2012-11-23 10:48:45 UTC
The following program compiles successfully and outputs nothing at all.  In fact, the generated assembly has an empty "main".  This happens even when compiling with -O0.

#include <iostream>

struct S {
  S() { }
};

int main()
{
  std::cout << new S[0] << " bla" << std::endl;
}

$  g++ new-opt.cc -Wall -Wextra 
$ ./a.out 
(no output)

The issue goes away when removing the default constructor of "S".  It seems gcc believes array-new with zero size is undefined behavior and thus removes the rest of the expression.  I can't follow the "undefined behavior" part; array-new with zero size should yield a non-zero pointer (see 3.7.3.1p2 [basic.stc.dynamic.allocation] and 5.3.4p7 [expr.new]).
Comment 1 Daniel Krügler 2012-11-23 22:21:30 UTC
I observe the same thing with gcc 4.8.0 20121104 (experimental) on my mingw-x86_64 system. Odd.
Comment 2 Paolo Carlini 2012-11-23 22:28:26 UTC
Yes, this is confirmed.
Comment 3 Paolo Carlini 2012-11-24 00:30:40 UTC
build_new_1, called by build_new, returns error_mark_node.

This happens because something goes very badly wrong in the cp_build_binary_op call around line 2712: essentially it computes 0 - 1!
Comment 4 Paolo Carlini 2012-11-24 01:24:38 UTC
And it's a regression.
Comment 5 Paolo Carlini 2012-11-24 01:52:49 UTC
And it's mine because I caused it with the fix for PR45385 :(
Comment 6 Harald van Dijk 2012-11-24 09:28:44 UTC
A compile-only test for this can be

struct S { S(); };
void f(S *);
void g() {
  S *s = new S[0];
  f(s);
}

which causes a bogus warning:

test.cc: In function 'void g()':
test.cc:5:7: warning: 's' is used uninitialized in this function [-Wuninitialized]
Comment 7 Paolo Carlini 2012-11-24 09:32:48 UTC
Thanks. Relying on a warning seems a bit brittle, maybe a scan in the original dump would be good enough in terms of compile only testcases, but I sent to the mailing list a run time test.
Comment 8 Paolo Carlini 2012-11-24 10:04:27 UTC
Patch here:

  http://gcc.gnu.org/ml/gcc-patches/2012-11/msg01991.html
Comment 9 Harald van Dijk 2012-11-24 11:27:25 UTC
Ah, okay, an alternative compile-only testcase that does not rely on particular warnings would be

struct S { S(); };
__typeof__(new S[0]) s;

test.cc:2:23: error: invalid type in declaration before ';' token

but if you've already got a good testcase, sure, go with that :)
Comment 10 paolo@gcc.gnu.org 2012-11-24 23:45:49 UTC
Author: paolo
Date: Sat Nov 24 23:45:45 2012
New Revision: 193785

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=193785
Log:
/cp
2012-11-24  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/55446
	* init.c (build_vec_init): Do not early return error_mark_mode
	when integer_all_onesp (maxindex).

/testsuite
2012-11-24  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/55446
	* g++.dg/init/new41.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/init/new41.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/init.c
    trunk/gcc/testsuite/ChangeLog
Comment 11 paolo@gcc.gnu.org 2012-11-24 23:55:26 UTC
Author: paolo
Date: Sat Nov 24 23:55:22 2012
New Revision: 193786

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=193786
Log:
/cp
2012-11-24  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/55446
	* init.c (build_vec_init): Do not early return error_mark_mode
	when integer_all_onesp (maxindex).

/testsuite
2012-11-24  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/55446
	* g++.dg/init/new41.C: New.

Added:
    branches/gcc-4_7-branch/gcc/testsuite/g++.dg/init/new41.C
Modified:
    branches/gcc-4_7-branch/gcc/cp/ChangeLog
    branches/gcc-4_7-branch/gcc/cp/init.c
    branches/gcc-4_7-branch/gcc/testsuite/ChangeLog
Comment 12 Paolo Carlini 2012-11-24 23:56:20 UTC
Fixed.
Comment 13 Paolo Carlini 2013-01-30 10:19:05 UTC
*** Bug 56146 has been marked as a duplicate of this bug. ***