Hi,

On 15/06/2016 03:30, Jason Merrill wrote:
On Tue, Jun 14, 2016 at 6:12 PM, Paolo Carlini <paolo.carl...@oracle.com> wrote:
constexpr-specialization.C:7:26: error: redeclaration ‘constexpr int foo(T)
[with T = int]’ differs in ‘constexpr’

constexpr-specialization.C:6:16: error: from previous declaration ‘constexpr
int foo(T) [with T = int]’

see? The pretty printing of the previous declaration is very misleading
because it has constexpr in it!
I'm guessing this happens because we're printing the type of the
template plus template arguments, and the template is declared
constexpr.  That should be easy enough to fix in dump_function_decl by
looking at the instantiation when deciding whether to print
"constexpr".
Indeed, it seems very easy to do and dump_function_decl should be fixed anyway, outside this specific error message. Also, we already had a similar issue for the exceptions. Thus the below, tested x86_64-linux.

Thanks,
Paolo.

//////////////////////
/cp
2016-06-15  Paolo Carlini  <paolo.carl...@oracle.com>

        * decl.c (validate_constexpr_redeclaration): Change pair of errors
        to error + inform.
        * error.c (dump_function_decl): Save the constexpr specifier too.

/testsuite
2016-06-15  Paolo Carlini  <paolo.carl...@oracle.com>

        * g++.dg/cpp0x/constexpr-specialization.C: Adjust for dg-message
        vs dg-error; test constexpr specifier too.
Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 237472)
+++ cp/decl.c   (working copy)
@@ -1278,8 +1278,11 @@ validate_constexpr_redeclaration (tree old_decl, t
          && DECL_TEMPLATE_SPECIALIZATION (new_decl))
        return true;
 
-      error ("redeclaration %q+D differs in %<constexpr%>", new_decl);
-      error ("from previous declaration %q+D", old_decl);
+      error_at (DECL_SOURCE_LOCATION (new_decl),
+               "redeclaration %qD differs in %<constexpr%> "
+               "from previous declaration", new_decl);
+      inform (DECL_SOURCE_LOCATION (old_decl),
+             "previous declaration %qD", old_decl);
       return false;
     }
   return true;
Index: cp/error.c
===================================================================
--- cp/error.c  (revision 237472)
+++ cp/error.c  (working copy)
@@ -1486,6 +1486,7 @@ dump_function_decl (cxx_pretty_printer *pp, tree t
   int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
   int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
   tree exceptions;
+  bool constexpr_p;
 
   flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME);
   if (TREE_CODE (t) == TEMPLATE_DECL)
@@ -1495,6 +1496,10 @@ dump_function_decl (cxx_pretty_printer *pp, tree t
      emitting an error about incompatible specifications.  */
   exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t));
 
+  /* Likewise for the constexpr specifier, in case t is a specialization
+     and we are emitting an error about an incompatible redeclaration.  */
+  constexpr_p = DECL_DECLARED_CONSTEXPR_P (t);
+
   /* Pretty print template instantiations only.  */
   if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)
       && flag_pretty_templates)
@@ -1529,7 +1534,7 @@ dump_function_decl (cxx_pretty_printer *pp, tree t
       else if (DECL_VIRTUAL_P (t))
        pp_cxx_ws_string (pp, "virtual");
 
-      if (DECL_DECLARED_CONSTEXPR_P (t))
+      if (constexpr_p)
        pp_cxx_ws_string (pp, "constexpr");
     }
 
Index: testsuite/g++.dg/cpp0x/constexpr-specialization.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-specialization.C   (revision 237472)
+++ testsuite/g++.dg/cpp0x/constexpr-specialization.C   (working copy)
@@ -3,10 +3,10 @@
 
 template<typename T> constexpr int foo(T);
 template<> int foo(int);
-template<> int foo(int);            // { dg-error "previous" }
-template<> constexpr int foo(int);  // { dg-error "redeclaration" }
+template<> int foo(int);            // { dg-message "previous declaration 'int 
foo" }
+template<> constexpr int foo(int);  // { dg-error "redeclaration 'constexpr 
int foo" }
 
 template<typename T> int bar(T);
 template<> constexpr int bar(int);
-template<> constexpr int bar(int);  // { dg-error "previous" }
-template<> int bar(int);            // { dg-error "redeclaration" }
+template<> constexpr int bar(int);  // { dg-message "previous declaration 
'constexpr int bar" }
+template<> int bar(int);            // { dg-error "redeclaration 'int bar" }

Reply via email to