From patchwork Fri May 27 04:01:28 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 97653 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 EC90EB6F8B for ; Fri, 27 May 2011 14:01:48 +1000 (EST) Received: (qmail 1487 invoked by alias); 27 May 2011 04:01:46 -0000 Received: (qmail 1469 invoked by uid 22791); 27 May 2011 04:01:45 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_TM, T_RP_MATCHES_RCVD 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; Fri, 27 May 2011 04:01:29 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p4R41T5i008961 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 27 May 2011 00:01:29 -0400 Received: from [127.0.0.1] (ovpn-113-23.phx2.redhat.com [10.3.113.23]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p4R41SxB009599 for ; Fri, 27 May 2011 00:01:28 -0400 Message-ID: <4DDF2218.7050704@redhat.com> Date: Fri, 27 May 2011 00:01:28 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Lightning/1.0b2 Thunderbird/3.1.10 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/47956 (missing diagnostic for non-const static) 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 struct A { static auto i = 42; }; is ill-formed because i is non-const, but we weren't noticing that because we were checking it before replacing the auto. Fixed by moving the check into cp_finish_decl. It also seems we were incorrectly setting DECL_INITIALIZED_IN_CLASS for some template static data members; I had to fix that to avoid testsuite regressions. Tested x86_64-pc-linux-gnu, applying to trunk. commit 5719ff482f5048956429380ed6938e88c56d0962 Author: Jason Merrill Date: Thu May 26 14:44:27 2011 -0400 PR c++/47956 * decl.c (check_static_variable_definition): Now static. (cp_finish_decl): Call it here. (grokdeclarator): Not here. * pt.c (instantiate_class_template_1): Or here. * cp-tree.h: Don't declare it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ada01fb..a01253e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4895,7 +4895,6 @@ extern void finish_stmt (void); extern tree static_fn_type (tree); extern void revert_static_member_fn (tree); extern void fixup_anonymous_aggr (tree); -extern int check_static_variable_definition (tree, tree); extern tree compute_array_index_type (tree, tree, tsubst_flags_t); extern tree check_default_argument (tree, tree); typedef int (*walk_namespaces_fn) (tree, void *); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a956dbb..a524880 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -74,6 +74,7 @@ static void push_local_name (tree); static tree grok_reference_init (tree, tree, tree, tree *); static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *, int, int, tree); +static int check_static_variable_definition (tree, tree); static void record_unknown_type (tree, const char *); static tree builtin_function_1 (tree, tree, bool); static tree build_library_fn_1 (tree, enum tree_code, tree); @@ -5909,6 +5910,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (current_class_type && CP_DECL_CONTEXT (decl) == current_class_type && TYPE_BEING_DEFINED (current_class_type) + && !CLASSTYPE_TEMPLATE_INSTANTIATION (current_class_type) && (DECL_INITIAL (decl) || init)) DECL_INITIALIZED_IN_CLASS_P (decl) = 1; @@ -5939,6 +5941,11 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (!ensure_literal_type_for_constexpr_object (decl)) DECL_DECLARED_CONSTEXPR_P (decl) = 0; + if (TREE_CODE (decl) == VAR_DECL + && DECL_CLASS_SCOPE_P (decl) + && DECL_INITIALIZED_IN_CLASS_P (decl)) + check_static_variable_definition (decl, type); + if (init && TREE_CODE (decl) == FUNCTION_DECL) { tree clone; @@ -7640,9 +7647,12 @@ build_ptrmem_type (tree class_type, tree member_type) messages. Return 1 if the definition is particularly bad, or 0 otherwise. */ -int +static int check_static_variable_definition (tree decl, tree type) { + /* Can't check yet if we don't know the type. */ + if (dependent_type_p (type)) + return 0; /* If DECL is declared constexpr, we'll do the appropriate checks in check_initializer. */ if (DECL_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl)) @@ -10025,21 +10035,6 @@ grokdeclarator (const cp_declarator *declarator, staticp = 1; } } - - if (uses_template_parms (type)) - /* We'll check at instantiation time. */ - ; - else if (constexpr_p) - /* constexpr has the same requirements. */ - ; - else if (check_static_variable_definition (unqualified_id, - type)) - /* If we just return the declaration, crashes - will sometimes occur. We therefore return - void_type_node, as if this was a friend - declaration, to cause callers to completely - ignore this declaration. */ - return error_mark_node; } if (staticp) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ab48c8f..3b26700 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8414,8 +8414,6 @@ instantiate_class_template_1 (tree type) /*init_const_expr_p=*/false, /*asmspec_tree=*/NULL_TREE, /*flags=*/0); - if (DECL_INITIALIZED_IN_CLASS_P (r)) - check_static_variable_definition (r, TREE_TYPE (r)); } else if (TREE_CODE (r) == FIELD_DECL) { diff --git a/gcc/testsuite/g++.dg/cpp0x/auto7.C b/gcc/testsuite/g++.dg/cpp0x/auto7.C index 9ef5a80..e7ab723 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto7.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto7.C @@ -7,7 +7,7 @@ auto j; // { dg-error "has no initializer" } template struct A { - static auto k = 7; + static auto k = 7; // { dg-error "non-const" } static auto l; // { dg-error "has no initializer" } auto m; // { dg-error "has no initializer" } }; diff --git a/gcc/testsuite/g++.dg/template/crash50.C b/gcc/testsuite/g++.dg/template/crash50.C index 0060561..286685a 100644 --- a/gcc/testsuite/g++.dg/template/crash50.C +++ b/gcc/testsuite/g++.dg/template/crash50.C @@ -3,5 +3,5 @@ struct A { - template void* foo(; // { dg-error "primary-expression|initialization|static" } + template void* foo(; // { dg-error "primary-expression|initialization|static|template" } }; diff --git a/gcc/testsuite/g++.dg/template/static9.C b/gcc/testsuite/g++.dg/template/static9.C index 8845647..ab70101 100644 --- a/gcc/testsuite/g++.dg/template/static9.C +++ b/gcc/testsuite/g++.dg/template/static9.C @@ -3,7 +3,6 @@ template struct A { static const T i = 0; // { dg-error "declared void" "void" } - // { dg-error "invalid|non-literal" "invalid" { target *-*-* } 5 } }; A a; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.old-deja/g++.ext/memconst.C b/gcc/testsuite/g++.old-deja/g++.ext/memconst.C index 7dd2df7..d934763 100644 --- a/gcc/testsuite/g++.old-deja/g++.ext/memconst.C +++ b/gcc/testsuite/g++.old-deja/g++.ext/memconst.C @@ -21,5 +21,5 @@ public: void foo::bar () { - qwerty QWERTY ((unsigned short*)dummy_key); // { dg-error "" } + qwerty QWERTY ((unsigned short*)dummy_key); }