From f2cb6e64c920bb2f4e8a1ce9cb300385b53349ed Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 20 Jun 2018 19:07:37 +0000 Subject: [PATCH] decl.c (grokfndecl): Add const cp_decl_specifier_seq* parameter... /cp 2018-06-20 Paolo Carlini * decl.c (grokfndecl): Add const cp_decl_specifier_seq* parameter; tidy handling of a null location_t argument; use proper location information in a few additional error messages. (grokdeclarator): Update calls. /testsuite 2018-06-20 Paolo Carlini * g++.dg/template/friend65.C: New. * g++.dg/cpp0x/main1.C: Likewise. * g++.dg/other/main2.C: Likewise. * g++.dg/other/main3.C: Likewise. * g++.dg/template/friend42.C: Test location too. * g++.dg/concepts/decl-diagnose.C: Likewise. * g++.dg/warn/main-2.C: Update. From-SVN: r261816 --- gcc/cp/ChangeLog | 7 +++++ gcc/cp/decl.c | 42 +++++++++++++++------------ gcc/testsuite/ChangeLog | 10 +++++++ gcc/testsuite/g++.dg/concepts/decl-diagnose.C | 2 +- gcc/testsuite/g++.dg/cpp0x/main1.C | 3 ++ gcc/testsuite/g++.dg/other/main2.C | 1 + gcc/testsuite/g++.dg/other/main3.C | 1 + gcc/testsuite/g++.dg/template/friend42.C | 2 +- gcc/testsuite/g++.dg/template/friend65.C | 6 ++++ gcc/testsuite/g++.dg/warn/main-2.C | 4 +-- 10 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/main1.C create mode 100644 gcc/testsuite/g++.dg/other/main2.C create mode 100644 gcc/testsuite/g++.dg/other/main3.C create mode 100644 gcc/testsuite/g++.dg/template/friend65.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 56cecfa..b567d60 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2018-06-20 Paolo Carlini + + * decl.c (grokfndecl): Add const cp_decl_specifier_seq* parameter; + tidy handling of a null location_t argument; use proper location + information in a few additional error messages. + (grokdeclarator): Update calls. + 2018-06-20 Chung-Lin Tang Thomas Schwinge Cesar Philippidis diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f12a01b..b763b25 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8588,6 +8588,7 @@ grokfndecl (tree ctype, tree declarator, tree parms, tree orig_declarator, + const cp_decl_specifier_seq *declspecs, tree decl_reqs, int virtualp, enum overload_flags flags, @@ -8611,19 +8612,22 @@ grokfndecl (tree ctype, int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; tree t; + if (location == UNKNOWN_LOCATION) + location = input_location; + // Was the concept specifier present? bool concept_p = inlinep & 4; // Concept declarations must have a corresponding definition. if (concept_p && !funcdef_flag) { - error ("concept %qD has no definition", declarator); + error_at (location, "concept %qD has no definition", declarator); return NULL_TREE; } type = build_cp_fntype_variant (type, rqual, raises, late_return_type_p); - decl = build_lang_decl (FUNCTION_DECL, declarator, type); + decl = build_lang_decl_loc (location, FUNCTION_DECL, declarator, type); /* Set the constraints on the declaration. */ if (flag_concepts) @@ -8640,11 +8644,6 @@ grokfndecl (tree ctype, set_constraints (decl, ci); } - /* If we have an explicit location, use it, otherwise use whatever - build_lang_decl used (probably input_location). */ - if (location != UNKNOWN_LOCATION) - DECL_SOURCE_LOCATION (decl) = location; - if (TREE_CODE (type) == METHOD_TYPE) { tree parm = build_this_parm (decl, type, quals); @@ -8713,17 +8712,19 @@ grokfndecl (tree ctype, if (TREE_PURPOSE (t) && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG) { - error ("default arguments are not allowed in declaration " - "of friend template specialization %qD", - decl); + error_at (defarg_location (TREE_PURPOSE (t)), + "default arguments are not allowed in declaration " + "of friend template specialization %qD", + decl); return NULL_TREE; } if (inlinep & 1) { - error ("% is not allowed in declaration of friend " - "template specialization %qD", - decl); + error_at (declspecs->locations[ds_inline], + "% is not allowed in declaration of friend " + "template specialization %qD", + decl); return NULL_TREE; } } @@ -8770,13 +8771,15 @@ grokfndecl (tree ctype, if (ctype == NULL_TREE && DECL_MAIN_P (decl)) { if (PROCESSING_REAL_TEMPLATE_DECL_P()) - error ("cannot declare %<::main%> to be a template"); + error_at (location, "cannot declare %<::main%> to be a template"); if (inlinep & 1) - error ("cannot declare %<::main%> to be inline"); + error_at (declspecs->locations[ds_inline], + "cannot declare %<::main%> to be inline"); if (inlinep & 2) - error ("cannot declare %<::main%> to be %"); + error_at (declspecs->locations[ds_constexpr], + "cannot declare %<::main%> to be %"); if (!publicp) - error ("cannot declare %<::main%> to be static"); + error_at (location, "cannot declare %<::main%> to be static"); inlinep = 0; publicp = 1; } @@ -8989,7 +8992,8 @@ grokfndecl (tree ctype, { tree oldtypeargs = TYPE_ARG_TYPES (TREE_TYPE (decl)); tree newtype; - error ("%<::main%> must return %"); + error_at (declspecs->locations[ds_type_spec], + "%<::main%> must return %"); newtype = build_function_type (integer_type_node, oldtypeargs); TREE_TYPE (decl) = newtype; } @@ -12145,6 +12149,7 @@ grokdeclarator (const cp_declarator *declarator, ? unqualified_id : dname, parms, unqualified_id, + declspecs, reqs, virtualp, flags, memfn_quals, rqual, raises, friendp ? -1 : 0, friendp, publicp, @@ -12389,6 +12394,7 @@ grokdeclarator (const cp_declarator *declarator, || storage_class != sc_static); decl = grokfndecl (ctype, type, original_name, parms, unqualified_id, + declspecs, reqs, virtualp, flags, memfn_quals, rqual, raises, 1, friendp, publicp, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1c06223..8009196 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2018-06-20 Paolo Carlini + + * g++.dg/template/friend65.C: New. + * g++.dg/cpp0x/main1.C: Likewise. + * g++.dg/other/main2.C: Likewise. + * g++.dg/other/main3.C: Likewise. + * g++.dg/template/friend42.C: Test location too. + * g++.dg/concepts/decl-diagnose.C: Likewise. + * g++.dg/warn/main-2.C: Update. + 2018-06-20 Chung-Lin Tang Thomas Schwinge Cesar Philippidis diff --git a/gcc/testsuite/g++.dg/concepts/decl-diagnose.C b/gcc/testsuite/g++.dg/concepts/decl-diagnose.C index fcbfc8f..caf6b2e 100644 --- a/gcc/testsuite/g++.dg/concepts/decl-diagnose.C +++ b/gcc/testsuite/g++.dg/concepts/decl-diagnose.C @@ -6,7 +6,7 @@ void f(concept int); // { dg-error "a parameter cannot be declared 'concept'" } template concept int f2() { return 0; } // { dg-error "return type" } -concept bool f3(); // { dg-error "no definition" } +concept bool f3(); // { dg-error "14:concept .f3. has no definition" } struct X { diff --git a/gcc/testsuite/g++.dg/cpp0x/main1.C b/gcc/testsuite/g++.dg/cpp0x/main1.C new file mode 100644 index 0000000..4667c42 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/main1.C @@ -0,0 +1,3 @@ +// { dg-do compile { target c++11 } } + +constexpr int main(); // { dg-error "1:cannot declare .::main. to be .constexpr." } diff --git a/gcc/testsuite/g++.dg/other/main2.C b/gcc/testsuite/g++.dg/other/main2.C new file mode 100644 index 0000000..11fa09b --- /dev/null +++ b/gcc/testsuite/g++.dg/other/main2.C @@ -0,0 +1 @@ +float main(); // { dg-error "1:.::main. must return .int." } diff --git a/gcc/testsuite/g++.dg/other/main3.C b/gcc/testsuite/g++.dg/other/main3.C new file mode 100644 index 0000000..febd6fd --- /dev/null +++ b/gcc/testsuite/g++.dg/other/main3.C @@ -0,0 +1 @@ +inline int main(); // { dg-error "1:cannot declare .::main. to be inline" } diff --git a/gcc/testsuite/g++.dg/template/friend42.C b/gcc/testsuite/g++.dg/template/friend42.C index 73d10df..3b6ad5a 100644 --- a/gcc/testsuite/g++.dg/template/friend42.C +++ b/gcc/testsuite/g++.dg/template/friend42.C @@ -4,5 +4,5 @@ template void foo (int); template class Q { - friend void foo (int = 3); // { dg-error "default argument" } + friend void foo (int = 3); // { dg-error "27:default arguments are not allowed in declaration of friend" } }; diff --git a/gcc/testsuite/g++.dg/template/friend65.C b/gcc/testsuite/g++.dg/template/friend65.C new file mode 100644 index 0000000..8fa5654 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend65.C @@ -0,0 +1,6 @@ +template void foo (int); + +template +class Q { + friend inline void foo (int); // { dg-error "10:.inline. is not allowed in declaration of friend" } +}; diff --git a/gcc/testsuite/g++.dg/warn/main-2.C b/gcc/testsuite/g++.dg/warn/main-2.C index d38ef8e..6a46ff9 100644 --- a/gcc/testsuite/g++.dg/warn/main-2.C +++ b/gcc/testsuite/g++.dg/warn/main-2.C @@ -7,8 +7,8 @@ void f1(); -void -main() /* { dg-error "must return" } */ +void /* { dg-error "1:.\:\:main. must return .int." } */ +main() { f1(); } -- 2.7.4