aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-10-19 22:48:51 -0400
committerJason Merrill <jason@gcc.gnu.org>2015-10-19 22:48:51 -0400
commit2a9fb7125e0b0e73cc36ebbff607aa03d6e02ea4 (patch)
treece34d7922020e02b9e9d7346c70ded9a6f9f13c7 /gcc
parentdcdbc004d531b43e0583f8ac18def1474d64dc05 (diff)
downloadgcc-2a9fb7125e0b0e73cc36ebbff607aa03d6e02ea4.zip
gcc-2a9fb7125e0b0e73cc36ebbff607aa03d6e02ea4.tar.gz
gcc-2a9fb7125e0b0e73cc36ebbff607aa03d6e02ea4.tar.bz2
Implement N4268, Do constant evaluation of all non-type template args.
gcc/c-family/ * c-cppbuiltin.c (c_cpp_builtins): Define __cpp_nontype_template_args. gcc/cp/ * parser.c (cp_parser_template_argument): For C++1z just parse a constant-expression. * pt.c (convert_nontype_argument): For C++1z always call maybe_constant_value. From-SVN: r229019
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c-cppbuiltin.c1
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c9
-rw-r--r--gcc/cp/pt.c11
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nontype1.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nontype2.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nontype3.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nontype3a.C5
9 files changed, 87 insertions, 2 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index abcba29..46a6d74 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,6 +1,11 @@
2015-10-19 Jason Merrill <jason@redhat.com>
* c-cppbuiltin.c (c_cpp_builtins): Define
+ __cpp_nontype_template_args.
+
+2015-10-19 Jason Merrill <jason@redhat.com>
+
+ * c-cppbuiltin.c (c_cpp_builtins): Define
__cpp_enumerator_attributes, __cpp_fold_expressions,
__cpp_unicode_characters.
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index cd6fd51..c6c3d6b 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -876,6 +876,7 @@ c_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__cpp_enumerator_attributes=201411");
cpp_define (pfile, "__cpp_nested_namespace_definitions=201411");
cpp_define (pfile, "__cpp_fold_expressions=201411");
+ cpp_define (pfile, "__cpp_nontype_template_args=201411");
}
if (flag_concepts)
/* Use a value smaller than the 201507 specified in
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6bc52c3..842426b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2015-10-19 Jason Merrill <jason@redhat.com>
+ Implement N4268, Do constant evaluation of all non-type template args.
+ * parser.c (cp_parser_template_argument): For C++1z just parse a
+ constant-expression.
+ * pt.c (convert_nontype_argument): For C++1z always call
+ maybe_constant_value.
+
* constexpr.c (cxx_eval_constant_expression): Expand PTRMEM_CST
only when necessary.
(cxx_eval_component_reference): Like here.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 435757d..f07a5e4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -14977,8 +14977,12 @@ cp_parser_template_argument (cp_parser* parser)
warn_deprecated_use (argument, NULL_TREE);
return argument;
}
- /* It must be a non-type argument. There permitted cases are given
- in [temp.arg.nontype]:
+ /* It must be a non-type argument. In C++17 any constant-expression is
+ allowed. */
+ if (cxx_dialect > cxx14)
+ goto general_expr;
+
+ /* Otherwise, the permitted cases are given in [temp.arg.nontype]:
-- an integral constant-expression of integral or enumeration
type; or
@@ -15090,6 +15094,7 @@ cp_parser_template_argument (cp_parser* parser)
return error_mark_node;
}
+ general_expr:
/* If the argument wasn't successfully parsed as a type-id followed
by '>>', the argument can only be a constant expression now.
Otherwise, we try parsing the constant-expression tentatively,
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 14a5ddd..142245a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6233,6 +6233,17 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
CONSTRUCTOR. */;
else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
expr = maybe_constant_value (expr);
+ else if (cxx_dialect >= cxx1z)
+ {
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ expr = maybe_constant_value (expr);
+ else if (REFERENCE_REF_P (expr))
+ {
+ expr = TREE_OPERAND (expr, 0);
+ expr = maybe_constant_value (expr);
+ expr = convert_from_reference (expr);
+ }
+ }
else if (TYPE_PTR_OR_PTRMEM_P (type))
{
tree folded = maybe_constant_value (expr);
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype1.C b/gcc/testsuite/g++.dg/cpp1z/nontype1.C
new file mode 100644
index 0000000..bb46a99
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype1.C
@@ -0,0 +1,25 @@
+// { dg-options -std=c++1z }
+
+struct S { int m; static int s; } s;
+
+struct T: S { };
+
+template<int* p> class X { };
+template<const int S::*> class M {};
+template<const S&> class SP {};
+
+constexpr int *p = &S::s;
+constexpr int S::*sp = &T::m;
+constexpr S& sr = s;
+constexpr S& sf() { return s; }
+
+// { dg-final { scan-assembler "_Z1g1XIXadL_ZN1S1sEEEE" } }
+void g (X<&s.s>) { }
+// { dg-final { scan-assembler "_Z1f1XIXadL_ZN1S1sEEEE" } }
+void f (X<p>) { }
+// { dg-final { scan-assembler "_Z1f1MIXadL_ZN1S1mEEEE" } }
+void f (M<sp>) {}
+// { dg-final { scan-assembler "_Z1f2SPIL_Z1sEE" } }
+void f (SP<sr>) {}
+// { dg-final { scan-assembler "_Z1g2SPIL_Z1sEE" } }
+void g (SP<sf()>) {}
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype2.C b/gcc/testsuite/g++.dg/cpp1z/nontype2.C
new file mode 100644
index 0000000..e489476
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype2.C
@@ -0,0 +1,18 @@
+// { dg-options -std=c++1z }
+
+#include <typeinfo>
+
+struct S { int m; static int s; } s;
+
+template<int* p> class X { };
+template<const char *s> class Y {};
+template<const std::type_info &> class Z {};
+
+X<&s.m> x7; // { dg-error "" }
+Y<"foo"> y1; // { dg-error "string literal" }
+Z<typeid(p)> z1; // { dg-error "" }
+
+void f()
+{
+ Y<__func__> y; // { dg-error "" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype3.C b/gcc/testsuite/g++.dg/cpp1z/nontype3.C
new file mode 100644
index 0000000..886d7a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype3.C
@@ -0,0 +1,9 @@
+// { dg-options "-std=c++1z" }
+
+#ifndef __cpp_nontype_template_args
+#error __cpp_nontype_template_args not defined
+#endif
+
+#if __cpp_nontype_template_args != 201411
+#error Wrong value for __cpp_nontype_template_args
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype3a.C b/gcc/testsuite/g++.dg/cpp1z/nontype3a.C
new file mode 100644
index 0000000..a253d6b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype3a.C
@@ -0,0 +1,5 @@
+// This macro should not be defined without -std=c++1z.
+
+#ifdef __cpp_nontype_template_args
+#error __cpp_nontype_template_args defined
+#endif