diff options
author | Jason Merrill <jason@redhat.com> | 2019-08-15 17:55:19 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2019-08-15 17:55:19 -0400 |
commit | 7148dede8a84e17cc0b00190d76fabbc1a717654 (patch) | |
tree | f160ffecb6dcfc5746b9c4a402681d65b1e664fd /gcc/testsuite | |
parent | d321551cea11f27a9afd67ece9bbda095a579950 (diff) | |
download | gcc-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.C | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/cond15.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/cond16.C | 25 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.eh/cond1.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/cond5.C | 4 |
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" } |