Bug 85470 - [7 Regression] Strange error about "call to non-constexpr function"
Summary: [7 Regression] Strange error about "call to non-constexpr function"
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 7.3.0
: P2 normal
Target Milestone: 7.4
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2018-04-19 15:39 UTC by Mykhailo Kremniov
Modified: 2018-04-23 20:09 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-04-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mykhailo Kremniov 2018-04-19 15:39:01 UTC
GCC 7 fails to compile the following code:

---- test.cpp ----

template <class T>
struct StaticObject
{
    static T& create()
    {
      static T t;
      return t;
    }

    static T & instance;
};

template <class T> T & StaticObject<T>::instance = StaticObject<T>::create();

extern template class StaticObject<int>;

void test()
{
    StaticObject<int>::instance;
}

---- command line -----

$ g++-7.3.0 -v
Using built-in specs.
COLLECT_GCC=g++-7.3.0
COLLECT_LTO_WRAPPER=/home/brd/soft/gcc-7.3.0/libexec/gcc/x86_64-pc-linux-gnu/7.3.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ./configure --prefix=/home/brd/soft/gcc-7.3.0
Thread model: posix
gcc version 7.3.0 (GCC)

$ g++-7.3.0 -c test.cpp
test.cpp: In instantiation of ‘int& StaticObject<int>::instance’:
test.cpp:19:24:   required from here
test.cpp:13:75: error: call to non-constexpr function ‘static T& StaticObject<T>::create() [with T = int]’
 template <class T> T & StaticObject<T>::instance = StaticObject<T>::create();
 

P.S. I also tried 7.1 (same error) and 6.3 (no error)
Comment 1 Jakub Jelinek 2018-04-19 16:16:28 UTC
This is rejected starting with r242422.
Comment 2 Jakub Jelinek 2018-04-19 16:49:04 UTC
r200450 added
-      if (DECL_DECLARED_CONSTEXPR_P (decl))
+      if (DECL_DECLARED_CONSTEXPR_P (decl)
+	  || DECL_IN_AGGR_P (decl))
I wonder if it shouldn't have been DECL_INITIALIZED_IN_CLASS_P instead, or
DECL_IN_AGGR_P (decl) && DECL_INITIALIZED_IN_CLASS_P (decl).

If DECL_IN_AGGR_P (decl) check is right here, then the question is why it is set when there is the extern template line (and not otherwise).
Comment 3 Jakub Jelinek 2018-04-19 17:37:02 UTC
--- gcc/cp/typeck2.c.jj	2018-04-19 15:57:36.765482568 +0200
+++ gcc/cp/typeck2.c	2018-04-19 19:32:43.335986274 +0200
@@ -824,7 +824,9 @@ store_init_value (tree decl, tree init,
       bool const_init;
       value = fold_non_dependent_expr (value);
       if (DECL_DECLARED_CONSTEXPR_P (decl)
-	  || (DECL_IN_AGGR_P (decl) && !DECL_VAR_DECLARED_INLINE_P (decl)))
+	  || (DECL_CLASS_SCOPE_P (decl)
+	      && DECL_INITIALIZED_IN_CLASS_P (decl)
+	      && !DECL_VAR_DECLARED_INLINE_P (decl)))
 	{
 	  /* Diagnose a non-constant initializer for constexpr.  */
 	  if (!require_constant_expression (value))

just changes the error, from
pr85470.C:13:75: error: call to non-‘constexpr’ function ‘static T& StaticObject<T>::create() [with T = int]’
to
pr85470.C:13:24: error: non-constant in-class initialization invalid for static member ‘StaticObject<int>::instance’
cpp0x/overflow1.C still PASSes.
Comment 4 Jason Merrill 2018-04-23 19:11:54 UTC
Author: jason
Date: Mon Apr 23 19:11:22 2018
New Revision: 259571

URL: https://gcc.gnu.org/viewcvs?rev=259571&root=gcc&view=rev
Log:
	PR c++/85470 - wrong error with static data member.

	* decl.c (check_initializer): Check DECL_INITIALIZED_IN_CLASS_P.
	* typeck2.c (store_init_value): Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/extern_template-4.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/typeck2.c
Comment 5 Jason Merrill 2018-04-23 19:59:28 UTC
Author: jason
Date: Mon Apr 23 19:58:57 2018
New Revision: 259572

URL: https://gcc.gnu.org/viewcvs?rev=259572&root=gcc&view=rev
Log:
	PR c++/85470 - wrong error with static data member.

	* decl.c (check_initializer): Check DECL_INITIALIZED_IN_CLASS_P.
	* typeck2.c (store_init_value): Likewise.

Added:
    branches/gcc-7-branch/gcc/testsuite/g++.dg/cpp0x/extern_template-4.C
Modified:
    branches/gcc-7-branch/gcc/cp/ChangeLog
    branches/gcc-7-branch/gcc/cp/decl.c
    branches/gcc-7-branch/gcc/cp/typeck2.c
Comment 6 Jason Merrill 2018-04-23 20:09:28 UTC
Fixed.