From patchwork Tue Aug 30 21:32:07 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 112386 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 90231B6F85 for ; Wed, 31 Aug 2011 07:32:34 +1000 (EST) Received: (qmail 31618 invoked by alias); 30 Aug 2011 21:32:32 -0000 Received: (qmail 31608 invoked by uid 22791); 30 Aug 2011 21:32:31 -0000 X-SWARE-Spam-Status: No, hits=-6.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 30 Aug 2011 21:32:10 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p7ULWAb6010766 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 30 Aug 2011 17:32:10 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p7ULW93c009503 for ; Tue, 30 Aug 2011 17:32:09 -0400 Received: from [0.0.0.0] ([10.3.113.18]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p7ULW70d025851 for ; Tue, 30 Aug 2011 17:32:08 -0400 Message-ID: <4E5D56D7.8000509@redhat.com> Date: Tue, 30 Aug 2011 17:32:07 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:6.0) Gecko/20110817 Thunderbird/6.0 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/50084 (ICE with decltype and unnamed local class) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org In this testcase the compiler was incorrectly treating the typedef as giving a name to the class for linkage purposes, and then getting confused by that. While looking at this I noticed that nothing was actually looking at the user_defined_type_p bitfield, so I repurposed it. Tested x86_64-pc-linux-gnu, applying to trunk. commit bd3f1ed177f5ce0961f6482a3ea8a3dd1f9df336 Author: Jason Merrill Date: Tue Aug 30 16:46:14 2011 -0400 PR c++/50084 * cp-tree.h (cp_decl_specifier_seq): Rename user_defined_type_p to type_definition_p. * parser.c (cp_parser_set_decl_spec_type): Likewise. * decl.c (grokdeclarator): Check it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d125642..d18599b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4551,8 +4551,8 @@ typedef struct cp_decl_specifier_seq { /* The storage class specified -- or sc_none if no storage class was explicitly specified. */ cp_storage_class storage_class; - /* True iff TYPE_SPEC indicates a user-defined type. */ - BOOL_BITFIELD user_defined_type_p : 1; + /* True iff TYPE_SPEC defines a class or enum. */ + BOOL_BITFIELD type_definition_p : 1; /* True iff multiple types were (erroneously) specified for this decl-specifier-seq. */ BOOL_BITFIELD multiple_types_p : 1; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9090b11..39a0b0e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9643,6 +9643,7 @@ grokdeclarator (const cp_declarator *declarator, && TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && TYPE_ANONYMOUS_P (type) + && declspecs->type_definition_p && cp_type_quals (type) == TYPE_UNQUALIFIED) { tree t; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c862a7d..7d766d1 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12577,7 +12577,7 @@ cp_parser_type_specifier (cp_parser* parser, cp_parser_set_decl_spec_type (decl_specs, type_spec, token->location, - /*user_defined_p=*/true); + /*type_definition_p=*/true); return type_spec; } else @@ -12606,7 +12606,7 @@ cp_parser_type_specifier (cp_parser* parser, cp_parser_set_decl_spec_type (decl_specs, type_spec, token->location, - /*user_defined_p=*/true); + /*type_definition_p=*/true); return type_spec; } @@ -12628,7 +12628,7 @@ cp_parser_type_specifier (cp_parser* parser, cp_parser_set_decl_spec_type (decl_specs, type_spec, token->location, - /*user_defined_p=*/true); + /*type_definition_p=*/false); return type_spec; case RID_CONST: @@ -12821,7 +12821,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, if (decl_specs) cp_parser_set_decl_spec_type (decl_specs, type, token->location, - /*user_defined_p=*/true); + /*type_definition_p=*/false); return type; @@ -12831,7 +12831,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, if (decl_specs) cp_parser_set_decl_spec_type (decl_specs, type, token->location, - /*user_defined_p=*/true); + /*type_definition_p=*/false); return type; @@ -12848,7 +12848,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, if (decl_specs) cp_parser_set_decl_spec_type (decl_specs, type, token->location, - /*user_defined_p=*/true); + /*type_definition_p=*/false); cp_lexer_consume_token (parser->lexer); return type; } @@ -12865,7 +12865,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_set_decl_spec_type (decl_specs, type, token->location, - /*user_defined=*/false); + /*type_definition_p=*/false); if (decl_specs) decl_specs->any_specifiers_p = true; @@ -12940,7 +12940,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, if (type && decl_specs) cp_parser_set_decl_spec_type (decl_specs, type, token->location, - /*user_defined=*/true); + /*type_definition_p=*/false); } /* If we didn't get a type-name, issue an error message. */ @@ -21004,15 +21004,14 @@ cp_parser_set_storage_class (cp_parser *parser, decl_specs->conflicting_specifiers_p = true; } -/* Update the DECL_SPECS to reflect the TYPE_SPEC. If USER_DEFINED_P - is true, the type is a user-defined type; otherwise it is a - built-in type specified by a keyword. */ +/* Update the DECL_SPECS to reflect the TYPE_SPEC. If TYPE_DEFINITION_P + is true, the type is a class or enum definition. */ static void cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs, tree type_spec, location_t location, - bool user_defined_p) + bool type_definition_p) { decl_specs->any_specifiers_p = true; @@ -21022,7 +21021,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs, declarations so that G++ can work with system headers that are not C++-safe. */ if (decl_specs->specs[(int) ds_typedef] - && !user_defined_p + && !type_definition_p && (type_spec == boolean_type_node || type_spec == char16_type_node || type_spec == char32_type_node @@ -21037,7 +21036,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs, if (!decl_specs->type) { decl_specs->type = type_spec; - decl_specs->user_defined_type_p = false; + decl_specs->type_definition_p = false; decl_specs->type_location = location; } } @@ -21046,7 +21045,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs, else { decl_specs->type = type_spec; - decl_specs->user_defined_type_p = user_defined_p; + decl_specs->type_definition_p = type_definition_p; decl_specs->redefined_builtin_type = NULL_TREE; decl_specs->type_location = location; } diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype33.C b/gcc/testsuite/g++.dg/cpp0x/decltype33.C new file mode 100644 index 0000000..d022d16 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype33.C @@ -0,0 +1,18 @@ +// PR c++/50084 +// { dg-options "-std=c++0x -fno-inline" } + +template struct remove_reference; +template struct remove_reference { typedef T type; }; + +template void f(T) { } + +void g() +{ + struct { } * v = 0; + + typedef remove_reference::type at; + + // The typedef should't assign the name "at" to the struct. + // { dg-final { scan-assembler "_Z1fIZ1gvEUt_EvT_" } } + f(at()); +}