cp_parser_constant_expression wants an rvalue constant, so we shouldn't use it for parsing initializers, since the thing being initialized might be a reference. In C++98 it's OK because only integral statics can be initialized in the class, but in C++11 any type can be with the constexpr tag.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 820655889d7ea9f825769286823241fd6d0fbae5
Author: Jason Merrill <ja...@redhat.com>
Date:   Tue Sep 6 22:01:35 2011 -0400

    	PR c++/50298
    	* parser.c (cp_parser_member_declaration): Don't require a constant
    	rvalue here in C++0x.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7d766d1..6346aa0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -18187,6 +18187,17 @@ cp_parser_member_declaration (cp_parser* parser)
 		  initializer_token_start = cp_lexer_peek_token (parser->lexer);
 		  if (function_declarator_p (declarator))
 		    initializer = cp_parser_pure_specifier (parser);
+		  else if (cxx_dialect >= cxx0x)
+		    {
+		      bool nonconst;
+		      /* Don't require a constant rvalue in C++11, since we
+			 might want a reference constant.  We'll enforce
+		         constancy later.  */
+		      cp_lexer_consume_token (parser->lexer);
+		      /* Parse the initializer.  */
+		      initializer = cp_parser_initializer_clause (parser,
+								  &nonconst);
+		    }
 		  else
 		    /* Parse the initializer.  */
 		    initializer = cp_parser_constant_initializer (parser);
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ref3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref3.C
new file mode 100644
index 0000000..24cc9c8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref3.C
@@ -0,0 +1,10 @@
+// PR c++/50298
+// { dg-options -std=c++0x }
+
+int global_variable;
+
+template <class T> struct X {
+  static constexpr T r = global_variable;
+};
+
+X<int&> x;

Reply via email to