From: Jason Merrill <jason@redhat.com>
To: Martin Sebor <msebor@gmail.com>
Cc: Gcc Patch List <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] accept flexible arrays in struct in unions (c++/71912 - [6/7 regression])
Date: Thu, 06 Oct 2016 02:26:00 -0000 [thread overview]
Message-ID: <c9514eb4-b5da-f12d-5280-22612654b303@redhat.com> (raw)
In-Reply-To: <32325ceb-3d1a-def6-29f5-2f180035d1d5@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3527 bytes --]
On 10/05/2016 05:43 PM, Martin Sebor wrote:
> On 09/23/2016 12:00 PM, Jason Merrill wrote:
>> On Thu, Sep 22, 2016 at 7:39 PM, Martin Sebor <msebor@gmail.com> wrote:
>>> On 09/21/2016 02:43 PM, Jason Merrill wrote:
>>>> On Tue, Sep 20, 2016 at 1:01 PM, Martin Sebor <msebor@gmail.com> wrote:
>>>>> On 09/16/2016 12:19 PM, Jason Merrill wrote:
>>>>>> On 09/14/2016 01:03 PM, Martin Sebor wrote:
>>>>>>>
>>>>>>> + /* Type of the member. */
>>>>>>> + tree fldtype = TREE_CODE (fld) == FIELD_DECL ? TREE_TYPE
>>>>>>> (fld) : fld;
>>>>>>
>>>>>> Why set "fldtype" to be a TYPE_DECL rather than its type?
>>>>>
>>>>> I'm not sure I understand the question but (IIRC) the purpose of
>>>>> this code is to detect invalid uses of flexible array members in
>>>>> typedefs such as this:
>>>>>
>>>>> struct S { typedef struct { int i, a[]; } X2 [2]; };
>>>>>
>>>>> Sadly, it doesn't do anything for
>>>>>
>>>>> struct X { int i, a[]; };
>>>>> struct S { typedef struct X X2 [2]; };
>>>>
>>>> The issue is I don't see anything that uses fldtype as a decl, and
>>>> it's strange to have a variable called "*type" that can either be a
>>>> type or a decl, which later code still assumes will be a type.
>>>
>>> I suspect I'm simply looking at it from a different point of view.
>>> The definition
>>>
>>> tree fldtype = TREE_CODE (fld) == FIELD_DECL ? TREE_TYPE (fld) : fld
>>>
>>> denotes the type of the field if fld is a data member. Otherwise,
>>> it denotes a type (like a typedef).
>>
>> FLD is always a _DECL. The result of this assignment is that fldtype
>> refers to either a _TYPE or a _DECL. This creates a strange
>> asymmetry, and none of the following code seems to depend on it.
>> I would prefer
>>
>> tree fldtype = TREE_TYPE (fld);
>>
>> so that it's always a _TYPE.
>
> I mentioned that this code is important to avoid diagnosing typedefs,
> but the example I showed wasn't the right one. The examples that do
> depend on it are these two:
>
> struct S1 {
> typedef int A [0];
> A a;
> };
>
> struct S2 {
> typedef struct { int i, a[]; } A1;
> typedef struct { int i, a[]; } A2;
> };
>
> The expected (pedantic) warning is:
>
> warning: zero-size array member âS1::aâ in an otherwise empty âstruct S1â
>
> With the change you're asking we end up with:
>
> warning: zero-size array member âS1::aâ not at end of âstruct S1â
>
> followed by a bogus
>
> error: flexible array member âS2::A1::aâ not at end of âstruct S2â
>
> So I still don't understand what you're looking for. It sounds to
> me like you're asking me to rewrite the subsequent code that uses
> fldtype to use the expression above because you don't like that
> fldtype can be either a _DECL or _TYPE. But repeating that check
> four times doesn't make sense, so what am I missing?
I'm asking you to clarify the logic. It seems that your change to
fldtype affects these two tests:
> if (eltype == fldtype || TYPE_UNNAMED_P (eltype))
> if (TREE_CODE (fldtype) != ARRAY_TYPE)
...but this is extremely subtle. It would be a lot clearer to check fld
for FIELD_DECL or TYPE_DECL explicitly rather than relying on these
places that treat fldtype as a type to do the right thing because you've
obfuscated it. But I'm tired of going back and forth on this, so here's
a patch.
And now that I notice it, there seems to be no reason to handle typedefs
deep in the code for handling fields, it's simpler to handle them up top.
[-- Attachment #2: typedef.diff --]
[-- Type: text/x-patch, Size: 2580 bytes --]
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 03cf2eb..e6f7167 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6752,49 +6752,39 @@ find_flexarrays (tree t, flexmems_t *fmem, bool base_p,
typedef struct { int i, a[], j; } S; // bug c++/72753
S s [2]; // bug c++/68489
*/
- bool anon_type_p
- = (TREE_CODE (fld) == TYPE_DECL
- && DECL_IMPLICIT_TYPEDEF_P (fld)
- && anon_aggrname_p (DECL_NAME (fld)));
+ if (TREE_CODE (fld) == TYPE_DECL
+ && DECL_IMPLICIT_TYPEDEF_P (fld)
+ && CLASS_TYPE_P (TREE_TYPE (fld))
+ && anon_aggrname_p (DECL_NAME (fld)))
+ {
+ /* Check the nested unnamed type referenced via a typedef
+ independently of FMEM (since it's not a data member of
+ the enclosing class). */
+ check_flexarrays (TREE_TYPE (fld));
+ continue;
+ }
/* Skip anything that's GCC-generated or not a (non-static) data
- member or typedef. */
- if ((DECL_ARTIFICIAL (fld) && !anon_type_p)
- || (TREE_CODE (fld) != FIELD_DECL && TREE_CODE (fld) != TYPE_DECL))
+ member. */
+ if (DECL_ARTIFICIAL (fld) || TREE_CODE (fld) != FIELD_DECL)
continue;
/* Type of the member. */
- tree fldtype = TREE_CODE (fld) == FIELD_DECL ? TREE_TYPE (fld) : fld;
+ tree fldtype = TREE_TYPE (fld);
if (fldtype == error_mark_node)
return;
/* Determine the type of the array element or object referenced
by the member so that it can be checked for flexible array
members if it hasn't been yet. */
- tree eltype = TREE_TYPE (fld);
- if (eltype == error_mark_node)
- return;
-
+ tree eltype = fldtype;
while (TREE_CODE (eltype) == ARRAY_TYPE
|| TREE_CODE (eltype) == POINTER_TYPE
|| TREE_CODE (eltype) == REFERENCE_TYPE)
eltype = TREE_TYPE (eltype);
- if (TREE_CODE (fld) == TYPE_DECL
- && TYPE_CANONICAL (eltype) == TYPE_CANONICAL (t))
- continue;
-
if (RECORD_OR_UNION_TYPE_P (eltype))
{
- if (anon_type_p)
- {
- /* Check the nested unnamed type referenced via a typedef
- independently of FMEM (since it's not a data member of
- the enclosing class). */
- check_flexarrays (eltype);
- continue;
- }
-
if (fmem->array && !fmem->after[bool (pun)])
{
/* Once the member after the flexible array has been found
@@ -6843,8 +6833,6 @@ find_flexarrays (tree t, flexmems_t *fmem, bool base_p,
if (base_p)
continue;
}
- else if (TREE_CODE (fld) == TYPE_DECL)
- continue;
}
if (field_nonempty_p (fld))
next prev parent reply other threads:[~2016-10-06 2:26 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-22 19:14 Martin Sebor
2016-07-23 17:18 ` Martin Sebor
2016-07-26 18:53 ` Jason Merrill
2016-07-29 23:22 ` Martin Sebor
2016-07-31 16:28 ` Jason Merrill
2016-07-31 20:27 ` Martin Sebor
2016-08-01 14:22 ` Jason Merrill
2016-08-02 21:00 ` Martin Sebor
2016-08-02 22:26 ` Jason Merrill
2016-08-03 2:13 ` Martin Sebor
2016-08-03 18:05 ` Jason Merrill
2016-09-14 17:05 ` Martin Sebor
2016-09-16 18:40 ` Jason Merrill
2016-09-20 17:12 ` Martin Sebor
2016-09-21 20:55 ` Jason Merrill
2016-09-22 23:57 ` Martin Sebor
2016-09-23 18:05 ` Jason Merrill
2016-10-05 21:43 ` Martin Sebor
2016-10-06 2:26 ` Jason Merrill [this message]
2016-10-06 20:29 ` Martin Sebor
2016-10-12 1:46 ` PING " Martin Sebor
2016-10-12 13:43 ` Jason Merrill
2016-10-13 22:40 ` Martin Sebor
2016-08-03 19:10 ` Martin Sebor
2016-08-03 20:02 ` Jason Merrill
2016-08-03 20:23 ` Martin Sebor
2016-08-03 21:53 ` Jason Merrill
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c9514eb4-b5da-f12d-5280-22612654b303@redhat.com \
--to=jason@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=msebor@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).