Patchwork C++ PATCH for c++/46930 (ICE with uninitialized constexpr static data member)

login
register
mail settings
Submitter Jason Merrill
Date Dec. 14, 2010, 10:32 p.m.
Message ID <4D07F091.3040309@redhat.com>
Download mbox | patch
Permalink /patch/75575/
State New
Headers show

Comments

Jason Merrill - Dec. 14, 2010, 10:32 p.m.
A constexpr variable, must be initialized when it is declared; you can't 
forward declare a constexpr variable.  This applies to static data 
members, too.

Tested x86_64-pc-linux-gnu, applied to trunk.
commit 67091a3efa479b3611252b8174c878265f029a1a
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Dec 14 01:52:54 2010 -0500

    	PR c++/46930
    	* decl.c (grokdeclarator): Reject uninitialized constexpr
    	static data member.

Patch

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1be0f97..f9331bc 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9763,6 +9763,13 @@  grokdeclarator (const cp_declarator *declarator,
 
 		if (thread_p)
 		  DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+
+		if (constexpr_p && !initialized)
+		  {
+		    error ("constexpr static data member %qD must have an "
+			   "initializer", decl);
+		    constexpr_p = false;
+		  }
 	      }
 	    else
 	      {
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-decl.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-decl.C
new file mode 100644
index 0000000..0a3fcb6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-decl.C
@@ -0,0 +1,10 @@ 
+// PR c++/46930
+// { dg-options -std=c++0x }
+
+struct S {
+  static constexpr int size;	// { dg-error "must have an initializer" }
+  // { dg-error "previous declaration" "" { target *-*-* } 5 }
+};
+
+const int limit = 2 * S::size;
+constexpr int S::size = 256;	// { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C
index c7757f4..6b090a0 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C
@@ -16,9 +16,9 @@  struct S {
     constexpr int twice();
     constexpr int t();		// { dg-message "used but never defined" }
 private:
-    static constexpr int val;  // constexpr variable
+    static constexpr int val = 7;  // constexpr variable
 };
-constexpr int S::val = 7;
+
 constexpr int S::twice() { return val + val; }
 constexpr S s = { };
 int x1 = s.twice();     // ok
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-static5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-static5.C
index cb553a2..a401cc0 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-static5.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-static5.C
@@ -3,10 +3,10 @@ 
 template <class T>
 struct A
 {
-  constexpr static T t;
+  constexpr static T t = T();	// { dg-error "literal" }
 };
 template <class T>
-constexpr T A<T>::t = T();	// { dg-error "not literal" }
+constexpr T A<T>::t;
 
 struct B
 {