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
This commit is contained in:
parent
30b0317cb9
commit
5cf2a08413
|
@ -1,3 +1,10 @@
|
|||
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>
|
||||
|
||||
PR c++/56699
|
||||
|
|
|
@ -7427,13 +7427,16 @@ grokfndecl (tree ctype,
|
|||
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)
|
||||
{
|
||||
error ("%<inline%> is not allowed in declaration of friend "
|
||||
"template specialization %qD",
|
||||
decl);
|
||||
return NULL_TREE;
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7472,8 +7475,10 @@ grokfndecl (tree ctype,
|
|||
{
|
||||
if (PROCESSING_REAL_TEMPLATE_DECL_P())
|
||||
error ("cannot declare %<::main%> to be a template");
|
||||
if (inlinep)
|
||||
if (inlinep & 1)
|
||||
error ("cannot declare %<::main%> to be inline");
|
||||
if (inlinep & 2)
|
||||
error ("cannot declare %<::main%> to be constexpr");
|
||||
if (!publicp)
|
||||
error ("cannot declare %<::main%> to be static");
|
||||
inlinep = 0;
|
||||
|
@ -8651,6 +8656,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
|
||||
bool template_type_arg = 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);
|
||||
source_location saved_loc = input_location;
|
||||
const char *errmsg;
|
||||
|
@ -8862,7 +8868,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
|
||||
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);
|
||||
return error_mark_node;
|
||||
|
@ -8900,7 +8906,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
if (name == NULL)
|
||||
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");
|
||||
return error_mark_node;
|
||||
|
@ -9198,7 +9204,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
/* Issue errors about use of storage classes for parameters. */
|
||||
if (decl_context == PARM)
|
||||
{
|
||||
if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
|
||||
if (typedef_p)
|
||||
{
|
||||
error ("typedef declaration invalid in parameter declaration");
|
||||
return error_mark_node;
|
||||
|
@ -9242,7 +9248,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
&& ((storage_class
|
||||
&& storage_class != sc_extern
|
||||
&& storage_class != sc_static)
|
||||
|| decl_spec_seq_has_spec_p (declspecs, ds_typedef)))
|
||||
|| typedef_p))
|
||||
{
|
||||
error ("multiple storage classes in declaration of %qs", name);
|
||||
thread_p = false;
|
||||
|
@ -9256,7 +9262,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
&& (storage_class == sc_register
|
||||
|| storage_class == sc_auto))
|
||||
;
|
||||
else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
|
||||
else if (typedef_p)
|
||||
;
|
||||
else if (decl_context == FIELD
|
||||
/* C++ allows static class elements. */
|
||||
|
@ -9866,8 +9872,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)
|
||||
&& current_class_type)
|
||||
else if (typedef_p && current_class_type)
|
||||
{
|
||||
error ("cannot declare member %<%T::%s%> within %qT",
|
||||
ctype, name, current_class_type);
|
||||
|
@ -9944,8 +9949,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
error ("non-member %qs cannot be declared %<mutable%>", name);
|
||||
storage_class = sc_none;
|
||||
}
|
||||
else if (decl_context == TYPENAME
|
||||
|| decl_spec_seq_has_spec_p (declspecs, ds_typedef))
|
||||
else if (decl_context == TYPENAME || typedef_p)
|
||||
{
|
||||
error ("non-object member %qs cannot be declared %<mutable%>", name);
|
||||
storage_class = sc_none;
|
||||
|
@ -9975,7 +9979,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
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>
|
||||
|
||||
PR c++/56722
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// { 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" }
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
// { dg-do compile { target c++11 } }
|
||||
|
||||
constexpr int main (); // { dg-error "constexpr" }
|
Loading…
Reference in New Issue