Message ID | 673bd2d5-e060-8f2c-8c69-8139064fde45@oracle.com |
---|---|
State | New |
Headers | show |
On Fri, Mar 10, 2017 at 9:58 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote: > As such, the broken declaration cannot be rejected by the code we have in > finish_struct, something must happen earlier than that. It seems to me that > xref_tag_1 can be a good place, per the below patchlet, which passes testing > on x86_64-linux. I briefly wondered if making is_std_init_list stricter > would make sense instead, but I don't think so (consistently with the trail > of c++/60848 too): I believe that by the time we use is_std_init_list in the > internals we want something as simple as possible, we are assuming that > broken, fake, std::initializer_list aren't around in the translation unit. > In terms of details, I also wondered if CLASSTYPE_IS_TEMPLATE would make for > a better check, but seems unnecessarily more complex. Also, in principle, we > may want to have an even stricter check at declaration time (how many > template parameters, etc) but that seems overkilling and I don't think we > are risking ICEs because of that. I agree with all of this. How about in pushtag_1 instead, where we can return error_mark_node instead of aborting? Jason
Index: cp/decl.c =================================================================== --- cp/decl.c (revision 246023) +++ cp/decl.c (working copy) @@ -13645,6 +13645,13 @@ xref_tag_1 (enum tag_types tag_code, tree name, in push_template_decl. */ CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node; t = pushtag (name, t, scope); + if (t != error_mark_node + && CP_TYPE_CONTEXT (t) == std_node + && strcmp (TYPE_NAME_STRING (t), "initializer_list") == 0 + && !CLASSTYPE_TEMPLATE_INFO (t)) + fatal_error (input_location, + "declaration of std::initializer_list does not match " + "#include <initializer_list>, isn't a template"); } } else Index: testsuite/g++.dg/cpp0x/initlist97.C =================================================================== --- testsuite/g++.dg/cpp0x/initlist97.C (revision 0) +++ testsuite/g++.dg/cpp0x/initlist97.C (working copy) @@ -0,0 +1,9 @@ +// PR c++/77752 +// { dg-do compile { target c++11 } } + +namespace std { + class initializer_list; // { dg-message "initializer_list" } +} +void f(std::initializer_list l) { f({2}); } + +// { dg-prune-output "compilation terminated" }