aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2014-10-02 18:05:55 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2014-10-02 18:05:55 +0000
commit04bbdb1d08070dcc305d9de9e4d457fdee1116a5 (patch)
tree46375b3a304b70039984cb2f5164e74f2b071655 /gcc
parenta3ac63c46fd51fd3a531ae08e9f457e89e5744f9 (diff)
downloadgcc-04bbdb1d08070dcc305d9de9e4d457fdee1116a5.zip
gcc-04bbdb1d08070dcc305d9de9e4d457fdee1116a5.tar.gz
gcc-04bbdb1d08070dcc305d9de9e4d457fdee1116a5.tar.bz2
re PR c++/53025 ([C++11] noexcept operator depends on copy-elision)
/cp 2014-10-02 Paolo Carlini <paolo.carlini@oracle.com> PR c++/53025 * cp-tree.h (struct saved_scope): Add noexcept_operand. (cp_noexcept_operand): Define. * call.c (build_over_call): Use it. * parser.c (cp_parser_unary_expression, [RID_NOEXCEPT]): Likewise. * pt.c (tsubst_copy_and_build, [NOEXCEPT_EXPR]): Likewise. /testsuite 2014-10-02 Paolo Carlini <paolo.carlini@oracle.com> PR c++/53025 * g++.dg/cpp0x/noexcept23.C: New. * g++.dg/cpp0x/noexcept24.C: Likewise. From-SVN: r215813
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/call.c6
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept23.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept24.C22
8 files changed, 65 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a3cfa05..b5b3f59 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2014-10-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53025
+ * cp-tree.h (struct saved_scope): Add noexcept_operand.
+ (cp_noexcept_operand): Define.
+ * call.c (build_over_call): Use it.
+ * parser.c (cp_parser_unary_expression, [RID_NOEXCEPT]): Likewise.
+ * pt.c (tsubst_copy_and_build, [NOEXCEPT_EXPR]): Likewise.
+
2014-10-01 Jason Merrill <jason@redhat.com>
PR c++/63362
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 3c8b338..347070c 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7251,7 +7251,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
/* Do things the hard way. */;
else if (cand->num_convs == 1
&& (DECL_COPY_CONSTRUCTOR_P (fn)
- || DECL_MOVE_CONSTRUCTOR_P (fn)))
+ || DECL_MOVE_CONSTRUCTOR_P (fn))
+ /* It's unsafe to elide the constructor when handling
+ a noexcept-expression, it may evaluate to the wrong
+ value (c++/53025). */
+ && cp_noexcept_operand == 0)
{
tree targ;
tree arg = argarray[num_artificial_parms_for (fn)];
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 14ec837..fe1651e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1058,6 +1058,7 @@ struct GTY(()) saved_scope {
int unevaluated_operand;
int inhibit_evaluation_warnings;
+ int noexcept_operand;
/* If non-zero, implicit "omp declare target" attribute is added into the
attribute lists. */
int omp_declare_target_attribute;
@@ -1124,6 +1125,10 @@ struct GTY(()) saved_scope {
#define local_specializations scope_chain->x_local_specializations
+/* Nonzero if we are parsing the operand of a noexcept operator. */
+
+#define cp_noexcept_operand scope_chain->noexcept_operand
+
/* A list of private types mentioned, for deferred access checking. */
extern GTY(()) struct saved_scope *scope_chain;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 01b2fad..63ed1c0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7156,7 +7156,9 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
+ ++cp_noexcept_operand;
expr = cp_parser_expression (parser);
+ --cp_noexcept_operand;
--c_inhibit_evaluation_warnings;
--cp_unevaluated_operand;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f03e74c..d1dddff 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14769,11 +14769,13 @@ tsubst_copy_and_build (tree t,
op1 = TREE_OPERAND (t, 0);
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
+ ++cp_noexcept_operand;
op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
/*function_p=*/false,
/*integral_constant_expression_p=*/false);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
+ --cp_noexcept_operand;
RETURN (finish_noexcept_expr (op1, complain));
case MODOP_EXPR:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 760471c..d9aa1e5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-10-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53025
+ * g++.dg/cpp0x/noexcept23.C: New.
+ * g++.dg/cpp0x/noexcept24.C: Likewise.
+
2014-10-02 Marek Polacek <polacek@redhat.com>
* gcc.dg/noncompile/20020130-1.c: Use -std=gnu89.
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept23.C b/gcc/testsuite/g++.dg/cpp0x/noexcept23.C
new file mode 100644
index 0000000..5a01df4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept23.C
@@ -0,0 +1,14 @@
+// PR c++/53025
+// { dg-do compile { target c++11 } }
+
+struct A {
+ A() noexcept {}
+ A(const A&) noexcept(false) {}
+};
+
+void a(A) noexcept {}
+
+void f()
+{
+ static_assert(!noexcept(a(A{})), "");
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept24.C b/gcc/testsuite/g++.dg/cpp0x/noexcept24.C
new file mode 100644
index 0000000..c17ddfa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept24.C
@@ -0,0 +1,22 @@
+// PR c++/53025
+// { dg-do compile { target c++11 } }
+
+template<typename T>
+struct A {
+ A() noexcept {}
+ A(const A&) noexcept(false) {}
+};
+
+template<typename T>
+void a(A<T>) noexcept {}
+
+template<typename T>
+void f()
+{
+ static_assert(!noexcept(a(A<T>{})), "");
+}
+
+void g()
+{
+ f<int>();
+}