diff options
author | Patrick Palka <ppalka@redhat.com> | 2021-12-27 09:05:17 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2021-12-27 09:05:17 -0500 |
commit | 88cdcb5c18d73bfc9960d774c678f0e8103b8031 (patch) | |
tree | da511aa68bded7934886558d1f1f3297ffa0b5fd | |
parent | 9407058a430316db5299bc7867e4a31f900cd197 (diff) | |
download | gcc-88cdcb5c18d73bfc9960d774c678f0e8103b8031.zip gcc-88cdcb5c18d73bfc9960d774c678f0e8103b8031.tar.gz gcc-88cdcb5c18d73bfc9960d774c678f0e8103b8031.tar.bz2 |
c++: hard error w/ ptr+N and incomplete type [PR103700]
In pointer_int_sum when called from a SFINAE context, we need to avoid
calling size_in_bytes_loc on an incomplete pointed-to type since this
latter function isn't SFINAE-enabled and always emits an error on such
input.
PR c++/103700
gcc/c-family/ChangeLog:
* c-common.c (pointer_int_sum): When quiet, return
error_mark_node for an incomplete pointed-to type and don't
call size_in_bytes_loc.
gcc/testsuite/ChangeLog:
* g++.dg/template/sfinae32.C: New test.
-rw-r--r-- | gcc/c-family/c-common.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/sfinae32.C | 24 |
2 files changed, 26 insertions, 0 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index a25d59f..f3e3e9b 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -3308,6 +3308,8 @@ pointer_int_sum (location_t loc, enum tree_code resultcode, size_exp = integer_one_node; else { + if (!complain && !COMPLETE_TYPE_P (TREE_TYPE (result_type))) + return error_mark_node; size_exp = size_in_bytes_loc (loc, TREE_TYPE (result_type)); /* Wrap the pointer expression in a SAVE_EXPR to make sure it is evaluated first when the size expression may depend diff --git a/gcc/testsuite/g++.dg/template/sfinae32.C b/gcc/testsuite/g++.dg/template/sfinae32.C new file mode 100644 index 0000000..ae1dada --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae32.C @@ -0,0 +1,24 @@ +// PR c++/103700 +// { dg-do compile { target c++11 } } + +template<class T, int N> auto f(T* p) -> decltype(p + N); +template<class T, int N> auto f(T* p) -> decltype(p - N); +template<class T, int N> auto f(T* p) -> decltype(N + p); +template<class T, int N> void f(T* p); + +template<class T> auto g(T* p, int n) -> decltype(p + n); +template<class T> auto g(T* p, int n) -> decltype(p - n); +template<class T> auto g(T* p, int n) -> decltype(n + p); +template<class T> void g(T* p, int n); + +struct Incomplete; + +int main() { + f<Incomplete, 0>(nullptr); + f<Incomplete, 1>(nullptr); + f<Incomplete, -1>(nullptr); + f<Incomplete, 7>(nullptr); + f<Incomplete, -7>(nullptr); + + g<Incomplete>(nullptr, 0); +} |