Discussion:
C++ Patch for c++/60894
Fabien Chêne
2014-09-24 21:06:34 UTC
Permalink
Hi,

The problem here is that the use of an elaborated-type-specifier
(introduced via 'struct') does not find USING_DECLs, whereas it does
for a simple-type-specifier. That's caused by xref_tag (through
lookup_and_check_tag) that does not strip USING_DECLs and thus fails
to return a type when it happens to be the target of the USING_DECL.

Unfortunately, just stripping the USING_DECL in lookup_and_check_tag
does not really work because some diagnotic codes expect the
USING_DECL not to be stripped.
Consequently, I have fixed it by introcucing a new parameter to
xref_tag whose purpose is to know if stripping USING_DECLs is
desirable. Not very exciting to fix it this way, but that is the only
solution I managed to find.

Tested x86_64 linux without regressions. OK to commit to trunk ? And
branches after some weeks of incubation ?

gcc/cp/ChangeLog

2014-09-24 Fabien Chêne <***@gcc.gnu.org>

* cp-tree.h (xref_tag): Add a new bool parameter.
* parser.c (cp_parser_elaborated_type_specifier): Call xref_tag
with strip_using_p set to true.
(cp_parser_class_head): Call xref_tag with strip_using_p set to
false.
* rtti.c (init_rtti_processing): Likewise.
(build_dynamic_cast_1): Likewise.
(tinfo_base_init): Likewise.
(emit_support_tinfos): Likewise.
* lambda.c (begin_lambda_type): Likewise.
(vla_capture_type): Likewise.
* decl.c (lookup_and_check_tag): Add a new bool parameter. Strip
the USING_DECL if strip_using_p is set. Declare the variable t at
the use.
(xref_tag_1): Add a new bool parameter. Forward strip_using_p to
lookup_and_check_tag.
(xref_tag): Add a new bool parameter. Forward strip_using_p to
xref_tag_1.
(xref_tag_from_type): Call xref_tag with strip_using_p set to
false.
(start_enum): Call lookup_and_check_tag with strip_using_p set to
false. Call xref_tag with strip_using_p set to false.

gcc/testsuite/ChangeLog

2014-09-24 Fabien Chêne <***@gcc.gnu.org>

PR c++/56243
* g++.dg/lookup/using56.C: New.
--
Fabien
Jason Merrill
2014-09-24 21:15:48 UTC
Permalink
Post by Fabien Chêne
Unfortunately, just stripping the USING_DECL in lookup_and_check_tag
does not really work because some diagnotic codes expect the
USING_DECL not to be stripped.
How so?

Jason
Jason Merrill
2014-10-07 21:13:17 UTC
Permalink
Post by Fabien Chêne
Unfortunately, just stripping the USING_DECL in lookup_and_check_tag
does not really work because some diagnotic codes expect the
USING_DECL not to be stripped.
It seems to me that the problem is that lookup_and_check_tag is
rejecting a USING_DECL rather than returning it. What if we return the
USING_DECL?

Jason
Fabien Chêne
2014-10-08 17:30:24 UTC
Permalink
Post by Fabien Chêne
Unfortunately, just stripping the USING_DECL in lookup_and_check_tag
does not really work because some diagnotic codes expect the
USING_DECL not to be stripped.
It seems to me that the problem is that lookup_and_check_tag is rejecting a
USING_DECL rather than returning it. What if we return the USING_DECL?
If the USING_DECL is returned, the code below will be rejected as
expected, but the error message will not mention the line where the
USING_DECL appears as the previous definition, but at the target
declaration of the USING_DECL instead.

struct J
{
struct type {};
};

struct L : J
{
using J::type;
struct type {};
};

The code doing that is in cp_parser_class_head, after the call to
xref_tag, at this point:

if (type != error_mark_node && COMPLETE_TYPE_P (type))
{
error_at (type_start_token->location, "redefinition of %q#T",
type);
error_at (type_start_token->location, "previous definition of %q+#T",
type);
...

Actually, if xref_tag strips the USING_DECL, it finds a type already
complete and the original decl is lost for the diagnostic.
Trying to skip this error does not work because 'type' is really
expected not to be complete.
Hence, I guess the solution, however disgracious it could be, is to
ignore USING_DECLS from cp_parser_class_head through xref_tag, and
wait for the appropriate diagnostic at finish_struct (in
supplement_binding more precisely).
--
Fabien
Jason Merrill
2014-10-09 13:34:46 UTC
Permalink
Post by Fabien Chêne
It seems to me that the problem is that lookup_and_check_tag is rejecting a
USING_DECL rather than returning it. What if we return the USING_DECL?
If the USING_DECL is returned, the code below will be rejected as
expected, but the error message will not mention the line where the
USING_DECL appears as the previous definition, but at the target
declaration of the USING_DECL instead.
I think that's what happens if you strip the USING_DECL and return what
it points to; if you return the USING_DECL itself that shouldn't happen
(though then the caller needs to be able to deal with getting a USING_DECL).

Jason

Loading...