Only the first of the two functions is diagnosed for attempting to construct an int object in an array of size 1. The equivalent attempt in g() involving a multidimensional array with insufficient size is not diagnosed, either by -Wplacement-new or later by -Warray-bounds (or -Wstringop-overflow, although this warning is only meant to trigger for char accesses). $ cat t.C && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout t.C void* operator new (__SIZE_TYPE__, void *p) { return p; } char a[1]; char b[1][1]; void f () { new (&a[0]) int (123); // warning (good) } void g () { new (&b[0][0]) int (456); // no warning } t.C: In function ‘void f()’: t.C:8:8: warning: placement new constructing an object of type ‘int’ and size ‘4’ in a region of type ‘char [1]’ and size ‘1’ [-Wplacement-new=] 8 | new (&a[0]) int (123); // warning (good) | ^~~~~ ;; Function operator new (_ZnwmPv, funcdef_no=0, decl_uid=2337, cgraph_uid=1, symbol_order=0) operator new (long unsigned int D.2335, void * p) { <bb 2> [local count: 1073741824]: return p_1(D); } t.C:8:23: warning: writing 4 bytes into a region of size 1 [-Wstringop-overflow=] 8 | new (&a[0]) int (123); // warning (good) | ^ t.C:3:6: note: at offset 0 to object ‘a’ with size 1 declared here 3 | char a[1]; | ^ ;; Function f (_Z1fv, funcdef_no=1, decl_uid=2341, cgraph_uid=2, symbol_order=3) f () { <bb 2> [local count: 1073741824]: MEM[(int *)&a] = 123; return; } ;; Function g (_Z1gv, funcdef_no=2, decl_uid=2346, cgraph_uid=3, symbol_order=4) g () { <bb 2> [local count: 1073741824]: MEM[(int *)&b] = 456; return; }
It looks as though warn_placement_new_too_small() simply doesn't take into consideration milti-dimensional arrays. The missing -Warray-bounds warning is for the same reason as pr94195.