From 247ecdf3b8568e4b489598858b7586dccf9f95e5 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 8 Jan 2015 15:48:36 +0000 Subject: [PATCH] re PR c++/60753 (Deleted definition of an explicit function template specialization, following a declaration, incorrectly accepted) /cp 2015-01-08 Paolo Carlini PR c++/60753 * decl.c (grokfndecl): Add bool parameter. (grokdeclarator): Adjust calls. (start_decl): Don't set DECL_DELETED_FN here. /testsuite 2015-01-08 Paolo Carlini PR c++/60753 * g++.dg/cpp0x/deleted10.C: New. From-SVN: r219347 --- gcc/cp/ChangeLog | 7 +++++ gcc/cp/decl.c | 38 +++++++++++--------------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/cpp0x/deleted10.C | 15 ++++++++++ 4 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/deleted10.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f9322bfd839..5c576bc262b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2015-01-08 Paolo Carlini + + PR c++/60753 + * decl.c (grokfndecl): Add bool parameter. + (grokdeclarator): Adjust calls. + (start_decl): Don't set DECL_DELETED_FN here. + 2015-01-06 Jason Merrill * parser.c (cp_parser_nested_name_specifier_opt): Diagnose invalid diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2fea106771b..65ccf7745d2 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4631,26 +4631,15 @@ start_decl (const cp_declarator *declarator, if (context != global_namespace) *pushed_scope_p = push_scope (context); - if (initialized) - /* Is it valid for this decl to have an initializer at all? - If not, set INITIALIZED to zero, which will indirectly - tell `cp_finish_decl' to ignore the initializer once it is parsed. */ - switch (TREE_CODE (decl)) - { - case TYPE_DECL: - error ("typedef %qD is initialized (use decltype instead)", decl); - return error_mark_node; - - case FUNCTION_DECL: - if (initialized == SD_DELETED) - /* We'll handle the rest of the semantics later, but we need to - set this now so it's visible to duplicate_decls. */ - DECL_DELETED_FN (decl) = 1; - break; - - default: - break; - } + /* Is it valid for this decl to have an initializer at all? + If not, set INITIALIZED to zero, which will indirectly + tell `cp_finish_decl' to ignore the initializer once it is parsed. */ + if (initialized + && TREE_CODE (decl) == TYPE_DECL) + { + error ("typedef %qD is initialized (use decltype instead)", decl); + return error_mark_node; + } if (initialized) { @@ -7630,6 +7619,7 @@ grokfndecl (tree ctype, int friendp, int publicp, int inlinep, + bool deletedp, special_function_kind sfk, bool funcdef_flag, int template_count, @@ -7768,6 +7758,9 @@ grokfndecl (tree ctype, DECL_CONTEXT (decl) = ctype; } + if (deletedp) + DECL_DELETED_FN (decl) = 1; + if (ctype) { DECL_CONTEXT (decl) = ctype; @@ -10756,7 +10749,7 @@ grokdeclarator (const cp_declarator *declarator, virtualp, flags, memfn_quals, rqual, raises, friendp ? -1 : 0, friendp, publicp, inlinep | (2 * constexpr_p), - sfk, + initialized == SD_DELETED, sfk, funcdef_flag, template_count, in_namespace, attrlist, declarator->id_loc); decl = set_virt_specifiers (decl, virt_specifiers); @@ -10978,7 +10971,8 @@ grokdeclarator (const cp_declarator *declarator, decl = grokfndecl (ctype, type, original_name, parms, unqualified_id, virtualp, flags, memfn_quals, rqual, raises, 1, friendp, - publicp, inlinep | (2 * constexpr_p), sfk, + publicp, inlinep | (2 * constexpr_p), + initialized == SD_DELETED, sfk, funcdef_flag, template_count, in_namespace, attrlist, declarator->id_loc); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 356d20fe988..e692f4699d4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-01-08 Paolo Carlini + + PR c++/60753 + * g++.dg/cpp0x/deleted10.C: New. + 2015-01-07 David Malcolm * jit.dg/test-error-dereferencing-void-ptr.c: New test case. diff --git a/gcc/testsuite/g++.dg/cpp0x/deleted10.C b/gcc/testsuite/g++.dg/cpp0x/deleted10.C new file mode 100644 index 00000000000..4fbee27c333 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/deleted10.C @@ -0,0 +1,15 @@ +// PR c++/60753 +// { dg-do compile { target c++11 } } + +template void foo (T); + +template<> void foo (int); +template<> void foo (int) = delete; // { dg-error "deleted" } + +struct S +{ + template void bar (T); +}; + +template<> void S::bar (int); +template<> void S::bar (int) = delete; // { dg-error "deleted" } -- 2.30.2