This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/68710] New: flexible array member of a base class accepted in a non-empty derived class
- From: "msebor at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sat, 05 Dec 2015 00:17:46 +0000
- Subject: [Bug c++/68710] New: flexible array member of a base class accepted in a non-empty derived class
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68710
Bug ID: 68710
Summary: flexible array member of a base class accepted in a
non-empty derived class
Product: gcc
Version: 6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
G++ accepts definitions of non-empty derived classes whose base class contains
a flexible array member. While such base classes are valid on their own (for
compatibility with C), they cannot be derived from by non-empty classes that
contain data members of their own since accessing elements of the base class
would make it possible to access the derived class. The following example
shows why such constructs need to be rejected. The output shows that modifying
elements of the flexible array member modifies other members of the object.
The abort implies that GCC itself assumes that flexible array members do not
alias other members of the same object.
$ cat z.cpp && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -O2
-Wall -Wextra -Wpedantic -L ~/bin/gcc-5.1.0/lib64 -xc++ z.cpp && ./a.out
struct A {
const char *a;
const char *b[];
};
struct B: A {
const char *c;
};
extern "C" {
void free (void*);
void* malloc (__SIZE_TYPE__);
int printf (const char*, ...);
}
void foo (B *b)
{
const char* const s = "";
b->c = s;
b->b [0] = 0;
if (b->c != s)
__builtin_abort ();
}
int main ()
{
B *b = (B*)malloc (sizeof *b + 2 * sizeof *b->b);
b->a = "a";
b->c = "c";
b->b [0] = "b[0]";
b->b [1] = "b[1]";
b->b [2] = "b[2]";
b->b [3] = "b[3]";
printf ("{ { a = %s, b = { %s, %s, %s, %s } }, c = %s }\n",
b->a, b->b[0], b->b[1], b->b[2], b->b[3], b->c);
foo (b);
free (b);
}
z.cpp:3:19: warning: ISO C++ forbids zero-size array âbâ [-Wpedantic]
const char *b[];
^
{ { a = a, b = { b[0], b[1], b[2], b[3] } }, c = b[0] }
Aborted (core dumped)