Commit 5cf2a084 by Paolo Carlini Committed by Paolo Carlini

decl.c (grokfndecl): Handle separately <inline> and <constexpr> error messages.

/cp
2013-03-26  Paolo Carlini  <paolo.carlini@oracle.com>

	* decl.c (grokfndecl): Handle separately <inline> and <constexpr>
	error messages.

	* decl.c (grokdeclarator): Declare typedef_p and use it everywhere.

/testsuite
2013-03-26  Paolo Carlini  <paolo.carlini@oracle.com>

	* g++.dg/cpp0x/constexpr-friend-2.C: New.
	* g++.dg/cpp0x/constexpr-main.C: Likewise.

From-SVN: r197097
parent 30b0317c
2013-03-26 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (grokfndecl): Handle separately <inline> and <constexpr>
error messages.
* decl.c (grokdeclarator): Declare typedef_p and use it everywhere.
2013-03-25 Jason Merrill <jason@redhat.com> 2013-03-25 Jason Merrill <jason@redhat.com>
PR c++/56699 PR c++/56699
......
...@@ -7427,13 +7427,16 @@ grokfndecl (tree ctype, ...@@ -7427,13 +7427,16 @@ grokfndecl (tree ctype,
return NULL_TREE; return NULL_TREE;
} }
if (inlinep & 1)
error ("%<inline%> is not allowed in declaration of friend "
"template specialization %qD",
decl);
if (inlinep & 2)
error ("%<constexpr%> is not allowed in declaration of friend "
"template specialization %qD",
decl);
if (inlinep) if (inlinep)
{ return NULL_TREE;
error ("%<inline%> is not allowed in declaration of friend "
"template specialization %qD",
decl);
return NULL_TREE;
}
} }
} }
...@@ -7472,8 +7475,10 @@ grokfndecl (tree ctype, ...@@ -7472,8 +7475,10 @@ grokfndecl (tree ctype,
{ {
if (PROCESSING_REAL_TEMPLATE_DECL_P()) if (PROCESSING_REAL_TEMPLATE_DECL_P())
error ("cannot declare %<::main%> to be a template"); error ("cannot declare %<::main%> to be a template");
if (inlinep) if (inlinep & 1)
error ("cannot declare %<::main%> to be inline"); error ("cannot declare %<::main%> to be inline");
if (inlinep & 2)
error ("cannot declare %<::main%> to be constexpr");
if (!publicp) if (!publicp)
error ("cannot declare %<::main%> to be static"); error ("cannot declare %<::main%> to be static");
inlinep = 0; inlinep = 0;
...@@ -8651,6 +8656,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -8651,6 +8656,7 @@ grokdeclarator (const cp_declarator *declarator,
bool parameter_pack_p = declarator? declarator->parameter_pack_p : false; bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
bool template_type_arg = false; bool template_type_arg = false;
bool template_parm_flag = false; bool template_parm_flag = false;
bool typedef_p = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr); bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
source_location saved_loc = input_location; source_location saved_loc = input_location;
const char *errmsg; const char *errmsg;
...@@ -8862,7 +8868,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -8862,7 +8868,7 @@ grokdeclarator (const cp_declarator *declarator,
if (dname && IDENTIFIER_OPNAME_P (dname)) if (dname && IDENTIFIER_OPNAME_P (dname))
{ {
if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)) if (typedef_p)
{ {
error ("declaration of %qD as %<typedef%>", dname); error ("declaration of %qD as %<typedef%>", dname);
return error_mark_node; return error_mark_node;
...@@ -8900,7 +8906,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -8900,7 +8906,7 @@ grokdeclarator (const cp_declarator *declarator,
if (name == NULL) if (name == NULL)
name = decl_context == PARM ? "parameter" : "type name"; name = decl_context == PARM ? "parameter" : "type name";
if (constexpr_p && decl_spec_seq_has_spec_p (declspecs, ds_typedef)) if (constexpr_p && typedef_p)
{ {
error ("%<constexpr%> cannot appear in a typedef declaration"); error ("%<constexpr%> cannot appear in a typedef declaration");
return error_mark_node; return error_mark_node;
...@@ -9198,7 +9204,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -9198,7 +9204,7 @@ grokdeclarator (const cp_declarator *declarator,
/* Issue errors about use of storage classes for parameters. */ /* Issue errors about use of storage classes for parameters. */
if (decl_context == PARM) if (decl_context == PARM)
{ {
if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)) if (typedef_p)
{ {
error ("typedef declaration invalid in parameter declaration"); error ("typedef declaration invalid in parameter declaration");
return error_mark_node; return error_mark_node;
...@@ -9242,7 +9248,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -9242,7 +9248,7 @@ grokdeclarator (const cp_declarator *declarator,
&& ((storage_class && ((storage_class
&& storage_class != sc_extern && storage_class != sc_extern
&& storage_class != sc_static) && storage_class != sc_static)
|| decl_spec_seq_has_spec_p (declspecs, ds_typedef))) || typedef_p))
{ {
error ("multiple storage classes in declaration of %qs", name); error ("multiple storage classes in declaration of %qs", name);
thread_p = false; thread_p = false;
...@@ -9256,7 +9262,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -9256,7 +9262,7 @@ grokdeclarator (const cp_declarator *declarator,
&& (storage_class == sc_register && (storage_class == sc_register
|| storage_class == sc_auto)) || storage_class == sc_auto))
; ;
else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)) else if (typedef_p)
; ;
else if (decl_context == FIELD else if (decl_context == FIELD
/* C++ allows static class elements. */ /* C++ allows static class elements. */
...@@ -9866,8 +9872,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -9866,8 +9872,7 @@ grokdeclarator (const cp_declarator *declarator,
return error_mark_node; return error_mark_node;
} }
} }
else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef) else if (typedef_p && current_class_type)
&& current_class_type)
{ {
error ("cannot declare member %<%T::%s%> within %qT", error ("cannot declare member %<%T::%s%> within %qT",
ctype, name, current_class_type); ctype, name, current_class_type);
...@@ -9944,8 +9949,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -9944,8 +9949,7 @@ grokdeclarator (const cp_declarator *declarator,
error ("non-member %qs cannot be declared %<mutable%>", name); error ("non-member %qs cannot be declared %<mutable%>", name);
storage_class = sc_none; storage_class = sc_none;
} }
else if (decl_context == TYPENAME else if (decl_context == TYPENAME || typedef_p)
|| decl_spec_seq_has_spec_p (declspecs, ds_typedef))
{ {
error ("non-object member %qs cannot be declared %<mutable%>", name); error ("non-object member %qs cannot be declared %<mutable%>", name);
storage_class = sc_none; storage_class = sc_none;
...@@ -9975,7 +9979,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -9975,7 +9979,7 @@ grokdeclarator (const cp_declarator *declarator,
} }
/* If this is declaring a typedef name, return a TYPE_DECL. */ /* If this is declaring a typedef name, return a TYPE_DECL. */
if (decl_spec_seq_has_spec_p (declspecs, ds_typedef) && decl_context != TYPENAME) if (typedef_p && decl_context != TYPENAME)
{ {
tree decl; tree decl;
......
2013-03-26 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/cpp0x/constexpr-friend-2.C: New.
* g++.dg/cpp0x/constexpr-main.C: Likewise.
2013-03-25 Paolo Carlini <paolo.carlini@oracle.com> 2013-03-25 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/56722 PR c++/56722
......
// { dg-do compile { target c++11 } }
template<typename T> void f(T);
template <class T> class A {
friend constexpr void f<>(int); // { dg-error "'constexpr' is not allowed" }
};
// { dg-do compile { target c++11 } }
constexpr int main (); // { dg-error "constexpr" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment