aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-08-15 17:55:19 -0400
committerJason Merrill <jason@gcc.gnu.org>2019-08-15 17:55:19 -0400
commit7148dede8a84e17cc0b00190d76fabbc1a717654 (patch)
treef160ffecb6dcfc5746b9c4a402681d65b1e664fd /gcc/testsuite
parentd321551cea11f27a9afd67ece9bbda095a579950 (diff)
downloadgcc-7148dede8a84e17cc0b00190d76fabbc1a717654.zip
gcc-7148dede8a84e17cc0b00190d76fabbc1a717654.tar.gz
gcc-7148dede8a84e17cc0b00190d76fabbc1a717654.tar.bz2
PR c++/90393 - ICE with thow in ?:
My previous patch for 64372 was incomplete: it only stopped making the non-throw argument into an rvalue, lvalue_kind still considered the ?: expression to be an rvalue, leaving us worse than before. PR c++/64372, DR 1560 - Gratuitous lvalue-to-rvalue conversion in ?: * tree.c (lvalue_kind): Handle throw in one arm. * typeck.c (rationalize_conditional_expr): Likewise. (cp_build_modify_expr): Likewise. From-SVN: r274550
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle53.C5
-rw-r--r--gcc/testsuite/g++.dg/expr/cond15.C13
-rw-r--r--gcc/testsuite/g++.dg/expr/cond16.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/cond1.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/cond5.C4
5 files changed, 45 insertions, 6 deletions
diff --git a/gcc/testsuite/g++.dg/abi/mangle53.C b/gcc/testsuite/g++.dg/abi/mangle53.C
index 13f9e71..727fd75 100644
--- a/gcc/testsuite/g++.dg/abi/mangle53.C
+++ b/gcc/testsuite/g++.dg/abi/mangle53.C
@@ -1,10 +1,11 @@
// { dg-do compile { target c++11 } }
bool b;
+int i;
// { dg-final { scan-assembler "_Z1fIiEDTquL_Z1bEfp_twLi42EET_" } }
-template <class T> auto f (T t) -> decltype(b?t:throw 42) { return 0; }
+template <class T> auto f (T t) -> decltype(b?t:throw 42) { return i; }
// { dg-final { scan-assembler "_Z2f2IiEDTquL_Z1bEfp_trET_" } }
-template <class T> auto f2 (T t) -> decltype(b?t:throw) { return 0; }
+template <class T> auto f2 (T t) -> decltype(b?t:throw) { return i; }
int main()
{
diff --git a/gcc/testsuite/g++.dg/expr/cond15.C b/gcc/testsuite/g++.dg/expr/cond15.C
new file mode 100644
index 0000000..4a9d057
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/cond15.C
@@ -0,0 +1,13 @@
+// PR c++/90393
+
+struct S {
+ S();
+ S(const S&) {}
+};
+
+S f() {
+ const S m;
+ return true ? m : throw 0;
+}
+
+int main() {}
diff --git a/gcc/testsuite/g++.dg/expr/cond16.C b/gcc/testsuite/g++.dg/expr/cond16.C
new file mode 100644
index 0000000..796828b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/cond16.C
@@ -0,0 +1,25 @@
+// PR c++/90393
+// { dg-do run }
+
+int c, d;
+
+struct string {
+ string(const char *p): s(p) { ++c; }
+ ~string() { ++d; }
+ string(const string& str): s(str.s) { ++c; }
+ const char* s;
+ bool empty() const { return !s; }
+};
+
+string foo()
+{
+ string s("foo");
+ return s.empty() ? throw "empty" : s;
+}
+
+int main()
+{
+ foo();
+ if (c != d)
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/cond1.C b/gcc/testsuite/g++.old-deja/g++.eh/cond1.C
index 1b2de1d..fe6d429 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/cond1.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/cond1.C
@@ -22,8 +22,8 @@ void fn(int i)
(i ? throw X() : throw X()); // ok, void
(i ? i : j) = 1; // ok, int &
- (i ? throw X() : j) = 1; // { dg-error "" } non-lvalue
- (i ? j : throw X()) = 1; // { dg-error "" } non-lvalue
+ (i ? throw X() : j) = 1; // ok, int &
+ (i ? j : throw X()) = 1; // ok, int &
(i ? throw X() : throw X()) = 1; // { dg-error "" } void
(i ? (void)1 : i++); // { dg-error "" } ANSI forbids
diff --git a/gcc/testsuite/g++.old-deja/g++.other/cond5.C b/gcc/testsuite/g++.old-deja/g++.other/cond5.C
index f4d16e9..0d2baf9 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/cond5.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/cond5.C
@@ -35,8 +35,8 @@ void fn(int i)
(i ? throw X() : throw X()); // ok, void
(i ? i : j) = 1; // ok, int &
- (i ? throw X() : j) = 1; // { dg-error "lvalue" }
- (i ? j : throw X()) = 1; // { dg-error "lvalue" }
+ (i ? throw X() : j) = 1; // ok, int &
+ (i ? j : throw X()) = 1; // ok, int &
(i ? throw X() : throw X()) = 1; // { dg-error "lvalue" }
(i ? (void)1 : i++); // { dg-error "throw-expression" }