c++gccclangplacement-newinternal-compiler-error

Parenthesis around placement new operator for arrays


Playing around with placement new for arrays, I came up (by chance/mistake) with the following code:

#include <new>

struct X{};

int main()
{
    char buf[256];
    std::size_t n = 10;
    X* p = new (buf) (X[n]); // incorrect way, parenthesis by mistake
    //X* p = new (buf) X[n]; // correct way
}

The third line in main is incorrect, although it compiles. There shouldn't be any parenthesis. clang++ spits out

warning: when type is in parentheses, array cannot have dynamic size

while gcc6 outputs

warning: ISO C++ forbids variable length array [-Wvla] X* p = new (buf) (X[n]);

warning: non-constant array new length must be specified without parentheses around the type-id [-Wvla] X* p = new (buf) (X[n]);

then crashes with an internal compiler error (ICE) in tree_to_uhwi, at tree.h:4044. The internal compiler error appears only in gcc >= 6.

My question: how exactly is the line marked "incorrect" parsed/interpreted, why is it "wrong" to have those parentheses?*

*For the ICE, I'll fill out a bug anyway.

EDIT 1 I just realized that the ICE/warning(s) have nothing to do with user defined types, so the same behaviour is observed for int instead of struct X.

EDIT 2 gcc6 bug filled here. The ICE does not appear in gcc5 or earlier versions (only the warnings appear, which are correct).


Solution

  • With the parentheses, the type to be newed comes from a type-id, in this case X[n]. This is a variable length array which is not standard behavior. Without the parentheses, the type to be newed is a new-type-id, an array of X.