public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/marxin/heads/marxin-gcc-benchmark-branch)] c++: Fix ICE during constexpr virtual call evaluation [PR93633]
@ 2020-03-30 10:54 Martin Liska
  0 siblings, 0 replies; only message in thread
From: Martin Liska @ 2020-03-30 10:54 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:81958cd6adf402a85dc7d21b43caac56fba0af21

commit 81958cd6adf402a85dc7d21b43caac56fba0af21
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sun Feb 9 12:32:22 2020 +0100

    c++: Fix ICE during constexpr virtual call evaluation [PR93633]
    
    The first (valid) testcase ICEs because for
      A *a = new B ();
      a->foo (); // virtual method call
    we actually see &heap  and the "heap " objects don't have the class or
    whatever else type was used in new expression, but an array type containing
    one (or more of those for array new) and so when using TYPE_BINFO (objtype)
    on it we ICE.
    This patch handles this special case, and otherwise punts (as shown e.g. in
    the second testcase, where because the heap object is already deleted,
    we don't really want to allow it to be used.
    
    2020-02-09  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/93633
            * constexpr.c (cxx_eval_constant_expression): If obj is heap var with
            ARRAY_TYPE, use the element type.  Punt if objtype after that is not
            a class type.
    
            * g++.dg/cpp2a/constexpr-new11.C: New test.
            * g++.dg/cpp2a/constexpr-new12.C: New test.
            * g++.dg/cpp2a/constexpr-new13.C: New test.

Diff:
---
 gcc/cp/ChangeLog                             |  7 +++++++
 gcc/cp/constexpr.c                           | 11 ++++++++++
 gcc/testsuite/ChangeLog                      |  7 +++++++
 gcc/testsuite/g++.dg/cpp2a/constexpr-new11.C | 31 ++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C | 26 +++++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp2a/constexpr-new13.C | 26 +++++++++++++++++++++++
 6 files changed, 108 insertions(+)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index dff6a170580..90f26c90918 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2020-02-09  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/93633
+	* constexpr.c (cxx_eval_constant_expression): If obj is heap var with
+	ARRAY_TYPE, use the element type.  Punt if objtype after that is not
+	a class type.
+
 2020-02-08  Jason Merrill  <jason@redhat.com>
 
 	PR c++/90691
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 192ba566427..6495cf88e69 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -6063,6 +6063,17 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	       && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1)))
 	  obj = TREE_OPERAND (obj, 0);
 	tree objtype = TREE_TYPE (obj);
+	if (VAR_P (obj)
+	    && DECL_NAME (obj) == heap_identifier
+	    && TREE_CODE (objtype) == ARRAY_TYPE)
+	  objtype = TREE_TYPE (objtype);
+	if (!CLASS_TYPE_P (objtype))
+	  {
+	    if (!ctx->quiet)
+	      error_at (loc, "expression %qE is not a constant expression", t);
+	    *non_constant_p = true;
+	    return t;
+	  }
 	/* Find the function decl in the virtual functions list.  TOKEN is
 	   the DECL_VINDEX that says which function we're looking for.  */
 	tree virtuals = BINFO_VIRTUALS (TYPE_BINFO (objtype));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c47f3fb98dd..66806752bb6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2020-02-09  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/93633
+	* g++.dg/cpp2a/constexpr-new11.C: New test.
+	* g++.dg/cpp2a/constexpr-new12.C: New test.
+	* g++.dg/cpp2a/constexpr-new13.C: New test.
+
 2020-02-08  Andrew Pinski  <apinski@marvel.com>
 
 	PR target/91927
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new11.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new11.C
new file mode 100644
index 00000000000..26658d0a477
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new11.C
@@ -0,0 +1,31 @@
+// PR c++/93633
+// { dg-do compile { target c++2a } }
+
+struct A {
+  constexpr A () : a (0) {}
+  constexpr virtual int foo () { return 1 + a * 4; }
+  int a;
+};
+
+struct B : A {
+  constexpr B () : b (0) {}
+  constexpr virtual int foo () { return 0 + b * 4; }
+  int b;
+};
+
+constexpr int
+foo ()
+{
+  A *a = new B ();
+  a->a = 4;
+  int r = a->foo ();
+  delete a;
+  return r;
+}
+
+int
+main ()
+{
+  constexpr auto a = foo ();
+  static_assert (a == 0);
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C
new file mode 100644
index 00000000000..2dedcd22b58
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C
@@ -0,0 +1,26 @@
+// PR c++/93633
+// { dg-do compile { target c++2a } }
+
+struct A {
+  constexpr A () : a (0) {}
+  constexpr virtual int foo () { return 1 + a * 4; }
+  int a;
+};
+
+struct B : A {
+  constexpr B () : b (0) {}
+  constexpr virtual int foo () { return 0 + b * 4; }
+  int b;
+};
+
+constexpr int
+foo ()
+{
+  A *a = new B ();
+  a->a = 4;
+  delete a;
+  int r = a->foo ();
+  return r;
+}
+
+constexpr auto a = foo ();	// { dg-error "is not a constant expression" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new13.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new13.C
new file mode 100644
index 00000000000..21219039152
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new13.C
@@ -0,0 +1,26 @@
+// PR c++/93633
+// { dg-do compile { target c++2a } }
+
+struct A {
+  constexpr A () : a (0) {}
+  virtual int foo () { return 1 + a * 4; }
+  int a;
+};
+
+struct B : A {
+  constexpr B () : b (0) {}
+  virtual int foo () { return 0 + b * 4; }	// { dg-message "declared here" }
+  int b;
+};
+
+constexpr int
+foo ()
+{
+  A *a = new B ();
+  a->a = 4;
+  int r = a->foo ();	// { dg-error "call to non-.constexpr. function" }
+  delete a;
+  return r;
+}
+
+constexpr auto a = foo ();


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-03-30 10:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-30 10:54 [gcc(refs/users/marxin/heads/marxin-gcc-benchmark-branch)] c++: Fix ICE during constexpr virtual call evaluation [PR93633] Martin Liska

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).