[Bug c++/65579] [C++11] gcc requires definition of a static constexpr member even though it is not odr-used
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Mar 9 18:39:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65579
Martin Sebor <msebor at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |msebor at gcc dot gnu.org
Known to fail| |4.9.3, 5.3.0, 6.0
--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
Re-confirmed with today's top of trunk (6.0) and all prior supported versions
that implement constexpr. See below.
The difference between the template and non-template case is the readonly bit
that's set on the 's' field when S is an ordinary struct. The bit is clear
when S is a template. The bit gets set in the c_apply_type_quals_to_decl()
function in c-family/c-common.c called from the cp_apply_type_quals_to_decl()
function defined in cp/typeck.c. The latter function executes the following
condition just before calling c_apply_type_quals_to_decl(). COMPLETE_TYPE_P
(type) is false when S is a (specialization of a template), causing the
TYPE_QUAL_CONST to clear.
/* Avoid setting TREE_READONLY incorrectly. */
/* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr
constructor can produce constant init, so rely on cp_finish_decl to
clear TREE_READONLY if the variable has non-constant init. */
/* 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))
type_quals &= ~TYPE_QUAL_CONST;
c_apply_type_quals_to_decl (type_quals, decl);
When S is made complete by this point (e.g., by causing S<int> to be
instantiated, say by declaring an object of the type), the bit stays set and
the test program links.
The c_apply_type_quals_to_decl() function the does the following:
if ((type_quals & TYPE_QUAL_CONST)
|| (type && TREE_CODE (type) == REFERENCE_TYPE))
/* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr
constructor can produce constant init, so rely on cp_finish_decl to
clear TREE_READONLY if the variable has non-constant init. */
TREE_READONLY (decl) = 1;
The comments referencing constexpr suggest that TREE_READONLY should perhaps be
set here and then cleared in cp_finish_decl.
$ cat z.c && /home/msebor/build/gcc-trunk-svn/gcc/xgcc
-B/home/msebor/build/gcc-trunk-svn/gcc -Wall -Wextra -Wpedantic -xc++ z.c
template <typename>
struct S {
int i;
};
struct T {
static constexpr S<int> s = { 1 };
};
int main()
{
return T::s.i;
}
/tmp/ccqP3dAP.o: In function `main':
z.c:(.text+0x6): undefined reference to `T::s'
collect2: error: ld returned 1 exit status
More information about the Gcc-bugs
mailing list