From 2212ae955a8a8cb759a65ca06c2e5462924ed66c Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 5 Jun 2019 20:07:01 +0000 Subject: [PATCH] decl.c (smallest_type_location): New. /cp 2019-06-05 Paolo Carlini * decl.c (smallest_type_location): New. (check_special_function_return_type): Use it. (grokdeclarator): Lkewise. /testsuite 2019-06-05 Paolo Carlini * g++.dg/diagnostic/return-type-invalid-1.C: New. * g++.old-deja/g++.brendan/crash16.C: Adjust. * g++.old-deja/g++.law/ctors5.C: Likewise. /cp 2019-06-05 Paolo Carlini * decl.c (grokdeclarator): Use locations[ds_friend] in one place. /testsuite 2019-06-05 Paolo Carlini * g++.dg/other/friend4.C: Test locations too. * g++.dg/other/friend5.C: Likewise. * g++.dg/other/friend7.C: Likewise. From-SVN: r271974 --- gcc/cp/ChangeLog | 11 +++++++ gcc/cp/decl.c | 32 +++++++++++++------ gcc/testsuite/ChangeLog | 12 +++++++ .../g++.dg/diagnostic/return-type-invalid-1.C | 27 ++++++++++++++++ gcc/testsuite/g++.dg/other/friend4.C | 4 +-- gcc/testsuite/g++.dg/other/friend5.C | 2 +- gcc/testsuite/g++.dg/other/friend7.C | 2 +- .../g++.old-deja/g++.brendan/crash16.C | 3 +- gcc/testsuite/g++.old-deja/g++.law/ctors5.C | 3 +- 9 files changed, 80 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/diagnostic/return-type-invalid-1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0056cc26525..952541a781f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2019-06-05 Paolo Carlini + + * decl.c (smallest_type_location): New. + (check_special_function_return_type): Use it. + (grokdeclarator): Lkewise. + +2019-06-05 Paolo Carlini + + * decl.c (grokdeclarator): Use locations[ds_friend] + in one place. + 2019-06-05 Martin Sebor * call.c (build_conditional_expr_1): Adjust quoting and hyphenation. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f342f8b1c65..ca248111eb5 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10111,6 +10111,15 @@ smallest_type_quals_location (int type_quals, const location_t* locations) return loc; } +/* Returns the smallest among the latter and locations[ds_type_spec]. */ + +static location_t +smallest_type_location (int type_quals, const location_t* locations) +{ + location_t loc = smallest_type_quals_location (type_quals, locations); + return min_location (loc, locations[ds_type_spec]); +} + /* Check that it's OK to declare a function with the indicated TYPE and TYPE_QUALS. SFK indicates the kind of special function (if any) that this function is. OPTYPE is the type given in a conversion @@ -10129,7 +10138,8 @@ check_special_function_return_type (special_function_kind sfk, { case sfk_constructor: if (type) - error ("return type specification for constructor invalid"); + error_at (smallest_type_location (type_quals, locations), + "return type specification for constructor invalid"); else if (type_quals != TYPE_UNQUALIFIED) error_at (smallest_type_quals_location (type_quals, locations), "qualifiers are not allowed on constructor declaration"); @@ -10142,7 +10152,8 @@ check_special_function_return_type (special_function_kind sfk, case sfk_destructor: if (type) - error ("return type specification for destructor invalid"); + error_at (smallest_type_location (type_quals, locations), + "return type specification for destructor invalid"); else if (type_quals != TYPE_UNQUALIFIED) error_at (smallest_type_quals_location (type_quals, locations), "qualifiers are not allowed on destructor declaration"); @@ -10157,7 +10168,8 @@ check_special_function_return_type (special_function_kind sfk, case sfk_conversion: if (type) - error ("return type specified for %", optype); + error_at (smallest_type_location (type_quals, locations), + "return type specified for %", optype); else if (type_quals != TYPE_UNQUALIFIED) error_at (smallest_type_quals_location (type_quals, locations), "qualifiers are not allowed on declaration of " @@ -10168,7 +10180,8 @@ check_special_function_return_type (special_function_kind sfk, case sfk_deduction_guide: if (type) - error ("return type specified for deduction guide"); + error_at (smallest_type_location (type_quals, locations), + "return type specified for deduction guide"); else if (type_quals != TYPE_UNQUALIFIED) error_at (smallest_type_quals_location (type_quals, locations), "qualifiers are not allowed on declaration of " @@ -10438,10 +10451,8 @@ grokdeclarator (const cp_declarator *declarator, if (initialized > 1) funcdef_flag = true; - location_t typespec_loc = smallest_type_quals_location (type_quals, - declspecs->locations); - typespec_loc = min_location (typespec_loc, - declspecs->locations[ds_type_spec]); + location_t typespec_loc = smallest_type_location (type_quals, + declspecs->locations); if (typespec_loc == UNKNOWN_LOCATION) typespec_loc = input_location; @@ -11895,8 +11906,9 @@ grokdeclarator (const cp_declarator *declarator, { if (friendp) { - permerror (input_location, "member functions are implicitly " - "friends of their class"); + permerror (declspecs->locations[ds_friend], + "member functions are implicitly " + "friends of their class"); friendp = 0; } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bc521344987..c5d8c02d3b4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2019-06-05 Paolo Carlini + + * g++.dg/diagnostic/return-type-invalid-1.C: New. + * g++.old-deja/g++.brendan/crash16.C: Adjust. + * g++.old-deja/g++.law/ctors5.C: Likewise. + +2019-06-05 Paolo Carlini + + * g++.dg/other/friend4.C: Test locations too. + * g++.dg/other/friend5.C: Likewise. + * g++.dg/other/friend7.C: Likewise. + 2019-06-05 Segher Boessenkool * g++.target/powerpc/undef-bool-3.C: Add -maltivec to dg-options. diff --git a/gcc/testsuite/g++.dg/diagnostic/return-type-invalid-1.C b/gcc/testsuite/g++.dg/diagnostic/return-type-invalid-1.C new file mode 100644 index 00000000000..56be51263ff --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/return-type-invalid-1.C @@ -0,0 +1,27 @@ +struct S1 +{ + int S1(); // { dg-error "3:return type" } + int ~S1(); // { dg-error "3:return type" } + int operator int(); // { dg-error "3:return type" } +}; + +struct S2 +{ + const int S2(); // { dg-error "3:return type" } + const int ~S2(); // { dg-error "3:return type" } + const int operator int(); // { dg-error "3:return type" } +}; + +struct S3 +{ + volatile int S3(); // { dg-error "3:return type" } + volatile int ~S3(); // { dg-error "3:return type" } + volatile int operator int(); // { dg-error "3:return type" } +}; + +struct S4 +{ + const volatile int S4(); // { dg-error "3:return type" } + const volatile int ~S4(); // { dg-error "3:return type" } + const volatile int operator int(); // { dg-error "3:return type" } +}; diff --git a/gcc/testsuite/g++.dg/other/friend4.C b/gcc/testsuite/g++.dg/other/friend4.C index 537643df954..de5cfafc21f 100644 --- a/gcc/testsuite/g++.dg/other/friend4.C +++ b/gcc/testsuite/g++.dg/other/friend4.C @@ -3,6 +3,6 @@ struct A { - friend void A::foo(); // { dg-error "implicitly friends" } - friend A::~A(); // { dg-error "implicitly friends" } + friend void A::foo(); // { dg-error "3:member functions are implicitly friends" } + friend A::~A(); // { dg-error "3:member functions are implicitly friends" } }; diff --git a/gcc/testsuite/g++.dg/other/friend5.C b/gcc/testsuite/g++.dg/other/friend5.C index b0ec201fb38..f6780a4bfa6 100644 --- a/gcc/testsuite/g++.dg/other/friend5.C +++ b/gcc/testsuite/g++.dg/other/friend5.C @@ -5,5 +5,5 @@ struct A { - friend A::~A() {} /* { dg-error "implicitly friends of their class" } */ + friend A::~A() {} /* { dg-error "3:member functions are implicitly friends of their class" } */ }; diff --git a/gcc/testsuite/g++.dg/other/friend7.C b/gcc/testsuite/g++.dg/other/friend7.C index 4d22a8791fd..56d994d63df 100644 --- a/gcc/testsuite/g++.dg/other/friend7.C +++ b/gcc/testsuite/g++.dg/other/friend7.C @@ -5,5 +5,5 @@ struct A { - friend A::~A() {} // { dg-error "implicitly friends of their class" } + friend A::~A() {} // { dg-error "3:member functions are implicitly friends of their class" } }; diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C index 5e6acc8c61c..2edb2a8711b 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C @@ -3,12 +3,13 @@ // GROUPS passed old-abort class Graph { // { dg-error "1:new types|1: note: \\(perhaps" } +// { dg-error "1:return type" "" { target *-*-* } .-1 } public: unsigned char N; Graph(void) {} // { dg-message "7:'Graph" } } -Graph::Graph(void) // { dg-error "18:return type|1: error: redefinition" } +Graph::Graph(void) // { dg-error "1:redefinition" } { N = 10; } diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors5.C b/gcc/testsuite/g++.old-deja/g++.law/ctors5.C index 96604e858b9..492c429ab17 100644 --- a/gcc/testsuite/g++.old-deja/g++.law/ctors5.C +++ b/gcc/testsuite/g++.old-deja/g++.law/ctors5.C @@ -16,13 +16,14 @@ class X // { dg-message "7:X::X|candidate expects" } implicit constructor class Y // { dg-error "1:new types may not be defined in a return type" "err" } // { dg-message "1:\\(perhaps a semicolon is missing after the definition of 'Y'\\)" "note" { target *-*-* } .-1 } + // { dg-error "1:return type specification for constructor invalid" "err" { target *-*-* } .-2 } { private: X xx; public: Y(); } -X::X( int xi ) // { dg-error "14:return type specification for constructor invalid" "err" } +X::X( int xi ) // { dg-message "1:X::X|candidate expects" "match candidate text" { target *-*-* } .-1 } { x = xi; -- 2.30.2