diff mbox

Fix PR c++/70204 (ICE in non_const_var_error)

Message ID 1458571107-6486-1-git-send-email-patrick@parcs.ath.cx
State New
Headers show

Commit Message

Patrick Palka March 21, 2016, 2:38 p.m. UTC
non_const_var_error() does not expect to complain about a decl whose
DECL_INITIAL is a constant.  But it is not sufficient to check that the
DECL_INITIAL is a constant since it could be the case that it was folded
to a constant and yet was originally initialized by a non-constant
expression.  So to avoid ICEing here, this patch makes
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P get checked as well.

Does this look OK to commit after testing?

gcc/cp/ChangeLog:

	PR c++/70204
	* constexpr.c (non_const_var_error): Check
	DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.

gcc/testsuite/ChangeLog:

	PR c++/70204
	* g++.dg/cpp0x/constexpr-70204a.C: New test.
	* g++.dg/cpp0x/constexpr-70204b.C: New test.
---
 gcc/cp/constexpr.c                            |  3 ++-
 gcc/testsuite/g++.dg/cpp0x/constexpr-70204a.C | 18 ++++++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/constexpr-70204b.C | 10 ++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-70204a.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-70204b.C

Comments

Jason Merrill March 21, 2016, 5:38 p.m. UTC | #1
On 03/21/2016 10:38 AM, Patrick Palka wrote:
> non_const_var_error() does not expect to complain about a decl whose
> DECL_INITIAL is a constant.  But it is not sufficient to check that the
> DECL_INITIAL is a constant since it could be the case that it was folded
> to a constant and yet was originally initialized by a non-constant
> expression.  So to avoid ICEing here, this patch makes
> DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P get checked as well.

Hmm, I wonder if we need the other checks, or if just checking that 
macro is good enough.  But your patch seems like the way to go for GCC 
6.  OK.

Jason
diff mbox

Patch

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 5f97c9d..5058c84 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -2756,7 +2756,8 @@  non_const_var_error (tree r)
 	inform (DECL_SOURCE_LOCATION (r),
 		"%q#D is volatile", r);
       else if (!DECL_INITIAL (r)
-	       || !TREE_CONSTANT (DECL_INITIAL (r)))
+	       || !TREE_CONSTANT (DECL_INITIAL (r))
+	       || !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r))
 	inform (DECL_SOURCE_LOCATION (r),
 		"%qD was not initialized with a constant "
 		"expression", r);
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-70204a.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-70204a.C
new file mode 100644
index 0000000..5ac5519
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-70204a.C
@@ -0,0 +1,18 @@ 
+// PR c++/70204
+// { dg-do compile { target c++11 } }
+
+int a;
+
+template < int N, int I >
+void fn1 ()
+{
+  const int x = I * a, y = x;
+  fn1 < y, I > (); // { dg-error "constant|no match" }
+}
+
+int
+main ()
+{
+  fn1 < 0, 0 > ();
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-70204b.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-70204b.C
new file mode 100644
index 0000000..2b07d4f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-70204b.C
@@ -0,0 +1,10 @@ 
+// PR c++/70204
+// { dg-do compile { target c++11 } }
+
+int a;
+
+void fn1 ()
+{
+  const int x = 0 * a;
+  constexpr int y = x; // { dg-error "constant" }
+}