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;