aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2013-03-26 10:23:59 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2013-03-26 10:23:59 +0000
commit5cf2a084134a8a7d376015981e55963f344d0f19 (patch)
tree5d6036a00149f5e9d47fe9bae08f27215a930686
parent30b0317cb922423802443127f526c7bfd4bbb61f (diff)
downloadgcc-5cf2a084134a8a7d376015981e55963f344d0f19.zip
gcc-5cf2a084134a8a7d376015981e55963f344d0f19.tar.gz
gcc-5cf2a084134a8a7d376015981e55963f344d0f19.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c38
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-main.C3
5 files changed, 43 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6aaf1dd..3dfb31a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2e5910c..a821328 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 46ad1ec..52a1a8d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C
new file mode 100644
index 0000000..36799b4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C
@@ -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" }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-main.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-main.C
new file mode 100644
index 0000000..42720ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-main.C
@@ -0,0 +1,3 @@
+// { dg-do compile { target c++11 } }
+
+constexpr int main (); // { dg-error "constexpr" }