decl.c (grokfndecl): Add const cp_decl_specifier_seq* parameter...
authorPaolo Carlini <paolo.carlini@oracle.com>
Wed, 20 Jun 2018 19:07:37 +0000 (19:07 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 20 Jun 2018 19:07:37 +0000 (19:07 +0000)
/cp
2018-06-20  Paolo Carlini  <paolo.carlini@oracle.com>

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

* 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
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/concepts/decl-diagnose.C
gcc/testsuite/g++.dg/cpp0x/main1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/main2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/main3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/friend42.C
gcc/testsuite/g++.dg/template/friend65.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/main-2.C

index 56cecfae45f906807f073775bf28b676e308e5b8..b567d60d129f51004cd6d430b3e75984c620637e 100644 (file)
@@ -1,3 +1,10 @@
+2018-06-20  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * 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 <cltang@codesourcery.com>
            Thomas Schwinge <thomas@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
index f12a01b28f555acbf099e3bc5a0906b8d223c376..b763b257c337cda266b59e820bf207f0733b1405 100644 (file)
@@ -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 ("%<inline%> is not allowed in declaration of friend "
-                    "template specialization %qD",
-                    decl);
+             error_at (declspecs->locations[ds_inline],
+                       "%<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 %<constexpr%>");
+       error_at (declspecs->locations[ds_constexpr],
+                 "cannot declare %<::main%> to be %<constexpr%>");
       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 %<int%>");
+         error_at (declspecs->locations[ds_type_spec],
+                   "%<::main%> must return %<int%>");
          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,
index 1c06223d668980df503ce2824ec70536c7b08ba4..800919666984ac4b6540a9cd2ff56fc4c8a903ec 100644 (file)
@@ -1,3 +1,13 @@
+2018-06-20  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * 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 <cltang@codesourcery.com>
            Thomas Schwinge <thomas@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
index fcbfc8f659587887e737c2aa56cf09d5e25a407a..caf6b2e5e3fd09519e3153dccbc63cfb54cd51c5 100644 (file)
@@ -6,7 +6,7 @@ void f(concept int); // { dg-error "a parameter cannot be declared 'concept'" }
 
 template<typename T>
 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 (file)
index 0000000..4667c42
--- /dev/null
@@ -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 (file)
index 0000000..11fa09b
--- /dev/null
@@ -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 (file)
index 0000000..febd6fd
--- /dev/null
@@ -0,0 +1 @@
+inline int main();  // { dg-error "1:cannot declare .::main. to be inline" }
index 73d10df01127a82b1a2a228af4e06cc2c0eb6381..3b6ad5a413377fb41064bb3e9a37632eb7619e05 100644 (file)
@@ -4,5 +4,5 @@ template <class T> void foo (int);
 
 template <class T>
 class Q {
-  friend void foo<T> (int = 3); // { dg-error "default argument" }
+  friend void foo<T> (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 (file)
index 0000000..8fa5654
--- /dev/null
@@ -0,0 +1,6 @@
+template <class T> void foo (int);
+
+template <class T>
+class Q {
+  friend inline void foo<T> (int); // { dg-error "10:.inline. is not allowed in declaration of friend" }
+};
index d38ef8e0912a50cc33f8a9d7cddc514a075dc2e3..6a46ff9bca666bdf801a4f1945e09c849f1bb258 100644 (file)
@@ -7,8 +7,8 @@
 
 void f1();  
   
-void
-main()  /* { dg-error "must return" } */
+void  /* { dg-error "1:.\:\:main. must return .int." } */
+main()
 {     
   f1();  
 }