decl.c (smallest_type_location): New.
authorPaolo Carlini <paolo.carlini@oracle.com>
Wed, 5 Jun 2019 20:07:01 +0000 (20:07 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 5 Jun 2019 20:07:01 +0000 (20:07 +0000)
/cp
2019-06-05  Paolo Carlini  <paolo.carlini@oracle.com>

* decl.c (smallest_type_location): New.
(check_special_function_return_type): Use it.
(grokdeclarator): Lkewise.

/testsuite
2019-06-05  Paolo Carlini  <paolo.carlini@oracle.com>

* 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  <paolo.carlini@oracle.com>

* decl.c (grokdeclarator): Use locations[ds_friend]
in one place.

/testsuite
2019-06-05  Paolo Carlini  <paolo.carlini@oracle.com>

* 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
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/diagnostic/return-type-invalid-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/friend4.C
gcc/testsuite/g++.dg/other/friend5.C
gcc/testsuite/g++.dg/other/friend7.C
gcc/testsuite/g++.old-deja/g++.brendan/crash16.C
gcc/testsuite/g++.old-deja/g++.law/ctors5.C

index 0056cc2..952541a 100644 (file)
@@ -1,3 +1,14 @@
+2019-06-05  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * decl.c (smallest_type_location): New.
+       (check_special_function_return_type): Use it.
+       (grokdeclarator): Lkewise.
+
+2019-06-05  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * decl.c (grokdeclarator): Use locations[ds_friend]
+       in one place.
+
 2019-06-05  Martin Sebor  <msebor@redhat.com>
 
        * call.c (build_conditional_expr_1): Adjust quoting and hyphenation.
index f342f8b..ca24811 100644 (file)
@@ -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 %<operator %T%>", optype);
+       error_at (smallest_type_location (type_quals, locations),
+                 "return type specified for %<operator %T%>", 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
index bc52134..c5d8c02 100644 (file)
@@ -1,3 +1,15 @@
+2019-06-05  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * 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  <paolo.carlini@oracle.com>
+
+       * 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  <segher@kernel.crashing.org>
 
        * 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 (file)
index 0000000..56be512
--- /dev/null
@@ -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" }
+};
index 537643d..de5cfaf 100644 (file)
@@ -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" }
 };
index b0ec201..f6780a4 100644 (file)
@@ -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" } */
 };
index 4d22a87..56d994d 100644 (file)
@@ -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" }
 };
index 5e6acc8..2edb2a8 100644 (file)
@@ -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;
 }
 
index 96604e8..492c429 100644 (file)
@@ -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;