aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-04-10 10:55:58 -0400
committerJason Merrill <jason@redhat.com>2021-04-10 16:33:11 -0400
commit82198676c80764ca7cf05f891afaee83b9179dd1 (patch)
treea9ab2b307a40e200e15998c040ca19d3d81b0cc9
parentec633d3777bd71f7bde5e671b61ec18e5b7b43ea (diff)
downloadgcc-82198676c80764ca7cf05f891afaee83b9179dd1.zip
gcc-82198676c80764ca7cf05f891afaee83b9179dd1.tar.gz
gcc-82198676c80764ca7cf05f891afaee83b9179dd1.tar.bz2
c++: ICE with invalid use of 'this' with static memfn [PR98800]
Here instantiation of the fake 'this' parameter we used when parsing the trailing return type of func() was failing because there is no actual 'this' parameter in the instantiation. For PR97399 I told Patrick to do the 'this' injection even for statics, but now I think I was wrong; the out-of-class definition case I was concerned about does not break with this patch. And we don't set current_class_ptr in the body of a static member function. And the OMP code should continue to parse 'this' and complain about it rather than give a syntax error. gcc/cp/ChangeLog: PR c++/98800 PR c++/97399 * parser.c (cp_parser_direct_declarator): Don't inject_this_parameter if static_p. (cp_parser_omp_var_list_no_open): Parse 'this' even if current_class_ptr isn't set for a better diagnostic. gcc/testsuite/ChangeLog: PR c++/98800 * g++.dg/gomp/this-1.C: Adjust diagnostic. * g++.dg/cpp0x/constexpr-this1.C: New test.
-rw-r--r--gcc/cp/parser.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-this1.C10
-rw-r--r--gcc/testsuite/g++.dg/gomp/this-1.C4
3 files changed, 13 insertions, 4 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e6e6ed7..b6f94bd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -22193,7 +22193,7 @@ cp_parser_direct_declarator (cp_parser* parser,
tree save_ccp = current_class_ptr;
tree save_ccr = current_class_ref;
- if (memfn && !friend_p)
+ if (memfn && !friend_p && !static_p)
/* DR 1207: 'this' is in scope after the cv-quals. */
inject_this_parameter (current_class_type, cv_quals);
@@ -35283,7 +35283,6 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
cp_parser_parse_tentatively (parser);
token = cp_lexer_peek_token (parser->lexer);
if (kind != 0
- && current_class_ptr
&& cp_parser_is_keyword (token, RID_THIS))
{
decl = finish_this_expr ();
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-this1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-this1.C
new file mode 100644
index 0000000..e50218d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-this1.C
@@ -0,0 +1,10 @@
+// PR c++/98800
+// { dg-do compile { target c++11 } }
+
+template <bool> struct enable_if_t {};
+struct tmp {
+ template <class> constexpr bool is_integral();
+ template <class E> static auto func() -> enable_if_t<is_integral<E>()>; // { dg-error "without object" }
+};
+template <class> constexpr bool tmp::is_integral() { return true; }
+int main() { tmp::func<int>(); } // { dg-error "no match" }
diff --git a/gcc/testsuite/g++.dg/gomp/this-1.C b/gcc/testsuite/g++.dg/gomp/this-1.C
index 30ab8b3..e7bd583 100644
--- a/gcc/testsuite/g++.dg/gomp/this-1.C
+++ b/gcc/testsuite/g++.dg/gomp/this-1.C
@@ -3,7 +3,7 @@
struct S
{
- #pragma omp declare simd linear(this) // { dg-error "is not a function argument" }
+ #pragma omp declare simd linear(this) // { dg-error "invalid use of .this" }
static void foo ();
void bar ();
};
@@ -35,7 +35,7 @@ S::bar ()
template <int N>
struct T
{
- #pragma omp declare simd linear(this) // { dg-error "is not a function argument" }
+ #pragma omp declare simd linear(this) // { dg-error "invalid use of .this" }
static void foo ();
void bar ();
};