Bug 59937 - [constexpr] bogus diagnostic "used in its own initializer"
Summary: [constexpr] bogus diagnostic "used in its own initializer"
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2014-01-24 23:39 UTC by Richard Smith
Modified: 2015-01-20 13:40 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-07-02 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Smith 2014-01-24 23:39:23 UTC
GCC rejects this:

constexpr const char * const &r = "";
constexpr const char * const &s = r;

with this bogus diagnostic:

test.cpp:2:35: error: the value of ‘r’ is not usable in a constant expression
 constexpr const char * const &s = r;
                                   ^
test.cpp:1:31: note: ‘r’ used in its own initializer
 constexpr const char * const &r = "";
                               ^
Comment 1 Jonathan Wakely 2014-07-02 09:30:37 UTC
Maybe related:

template<typename T> constexpr bool truth(const T&) { return true; }

template<typename T>
void test()
{
  int i[1];
  constexpr bool untrue = !truth(i);
  static_assert(!untrue, "");
}

ce.cc: In function ‘void test()’:
ce.cc:8:3: error: non-constant condition for static assertion
   static_assert(!untrue, "");
   ^
ce.cc:8:3: error: the value of ‘untrue’ is not usable in a constant expression
ce.cc:7:18: note: ‘untrue’ used in its own initializer
   constexpr bool untrue = !truth(i);
                  ^
Comment 2 Javier V. Gómez 2015-01-14 12:27:06 UTC
I found another case that worked in G++ 4.8.3 but fails in 4.9:

---------
main.cpp: 
---------
int main ()
{
    constexpr int n = 2;
    A<n> a;
    B b;
    b.foo();
}

---------
a.hpp: 
---------
template <size_t n> class A
{
    static constexpr size_t getN() {return n;}
};

---------
b.hpp: 
---------
class B 
{
    void foo ()
    {
        //has access to a A<n> object
        constexpr int n = a.getN();
        A<n> a2;
    }
};


Compiler output:
B.hpp: error: the value of ‘n’ is not usable in a constant expression
             A<n> a2;
               ^
B.hpp: note: ‘ndims’ used in its own initializer
             constexpr int n = a.getN();
                           ^
Comment 3 Jonathan Wakely 2015-01-14 12:49:06 UTC
(In reply to Javier V. Gómez from comment #2)
> I found another case that worked in G++ 4.8.3 but fails in 4.9:

This example is complete nonsense. Why is it split across three files? Why doesn't main.cpp include anything? Why is everything private? Why is 'a' undeclared in B::foo()? Why does the diagnostic talk about 'ndims' which isn't declared anywhere?

It's useless as a test or an example of the error.
Comment 4 Javier V. Gómez 2015-01-14 12:52:19 UTC
(In reply to Jonathan Wakely from comment #3)
> (In reply to Javier V. Gómez from comment #2)
> > I found another case that worked in G++ 4.8.3 but fails in 4.9:
> 
> This example is complete nonsense. Why is it split across three files? Why
> doesn't main.cpp include anything? Why is everything private? Why is 'a'
> undeclared in B::foo()? Why does the diagnostic talk about 'ndims' which
> isn't declared anywhere?
> 
> It's useless as a test or an example of the error.

I tried to simplify as much as possible the issue, since I detected the error in a big piece of code. I didn't pretend to create a compilable example. ndims is what I called n (copy and paste...).

The important point of my example is that constexpr int n = a.getN(); fails when A::getN() just returns a template parameter value previously set by a constexpr anywhere else.
Comment 5 Paolo Carlini 2015-01-20 13:14:11 UTC
This is fixed for 5.0. I'm adding the testcases and closing the bug.
Comment 6 paolo@gcc.gnu.org 2015-01-20 13:39:43 UTC
Author: paolo
Date: Tue Jan 20 13:39:10 2015
New Revision: 219894

URL: https://gcc.gnu.org/viewcvs?rev=219894&root=gcc&view=rev
Log:
2015-01-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/59937
	* g++.dg/cpp0x/constexpr-59937-1.C: New.
	* g++.dg/cpp0x/constexpr-59937-2.C: Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-59937-1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-59937-2.C
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 7 Paolo Carlini 2015-01-20 13:40:25 UTC
Done.