While going through constexpr bugs looking for background on one I'm currently working on I came across bug 65579 - [C++11] gcc requires definition of a static constexpr member even though it is not odr-used.
The bug points out that GCC (sometimes) emits references to static constexpr data members of class templates even when they aren't odr-used. (A more detailed analysis of why this happens is in my comment #1 on the bug.) The attached rather trivial patch seems to fix the problem and (somewhat to my surprise) pass regression tests on x86_64. Martin
PR c++/65579 - [C++11] gcc requires definition of a static constexpr member even though it is not odr-used gcc/testsuite/ChangeLog: 2016-03-09 Martin Sebor <mse...@redhat.com> PR c++/65579 * g++.dg/cpp0x/constexpr-static12.C: New test. gcc/cp/ChangeLog: 2016-03-09 Martin Sebor <mse...@redhat.com> PR c++/65579 * typeck.c (cp_apply_type_quals_to_decl): Make sure constexpr data members of a template type are marked readonly. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 20f0afc..690eaa8 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -9266,7 +9266,9 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl) /* If the type has (or might have) a mutable component, that component might be modified. */ - if (TYPE_HAS_MUTABLE_P (type) || !COMPLETE_TYPE_P (type)) + if (TYPE_HAS_MUTABLE_P (type) + || (!COMPLETE_TYPE_P (type) + && (!VAR_P (decl) || !DECL_DECLARED_CONSTEXPR_P (decl)))) type_quals &= ~TYPE_QUAL_CONST; c_apply_type_quals_to_decl (type_quals, decl); diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-static12.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-static12.C new file mode 100644 index 0000000..abf1d66 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-static12.C @@ -0,0 +1,23 @@ +// PR c++/65579 - [C++11] gcc requires definition of a static constexpr +// member even though it is not odr-used +// { dg-do compile { target c++11 } } + +template <int> +struct A +{ + int i; +}; + +struct B +{ + static constexpr A<0> constexpr_member = { 1 }; +}; + +int foo () +{ + return B::constexpr_member.i; +} + +// Verify that the constexpr_member reference has been folded away +// and isn't referenced in the assembly output. +// { dg-final { scan-assembler-not "constexpr_member" } }