Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 332829

Summary: [C++0x] Generalized constant expressions
Product: [Tools] CDT Reporter: Markus Schorn <mschorn.eclipse>
Component: cdt-parserAssignee: Nathan Ridge <zeratul976>
Status: RESOLVED FIXED QA Contact: Markus Schorn <mschorn.eclipse>
Severity: normal    
Priority: P3 CC: cdtdoug, eclipse.sprigogin, gpiez, olexiyb, vagran.ast, woskimi, yevshif, zeratul976
Version: 8.0   
Target Milestone: 8.4.0   
Hardware: PC   
OS: All   
Whiteboard:
Bug Depends on:    
Bug Blocks: 327297    
Attachments:
Description Flags
a test case that causes trouble none

Comment 1 Markus Schorn CLA 2011-11-02 06:24:35 EDT
*** Bug 361043 has been marked as a duplicate of this bug. ***
Comment 2 Gunther Piez CLA 2012-01-20 04:47:30 EST
I Have been hit by this now, this leads to not resolving std::chrono::duration_cast in gcc-4.6.2. Would it be possible to add it as an storage specifier like "__thread" or "thread_local"? The constness of the actual expression doesn't need to be proved by CDT IMHO.
Comment 3 Markus Schorn CLA 2012-01-20 06:44:04 EST
(In reply to comment #2)
> I Have been hit by this now, this leads to not resolving
> std::chrono::duration_cast in gcc-4.6.2. Would it be possible to add it as an
> storage specifier like "__thread" or "thread_local"? The constness of the
> actual expression doesn't need to be proved by CDT IMHO.

There are actually two parts for supporting this new feature:
* We need to handle the syntax, which should not be a big issue.
* For the purpose of template instantiation, CDT will have to be able to 
  evaluate the new kind of constant expressions. This involves storing
  expressions in the index. Therefore there is some relationship to bug 299911.
Comment 4 Sergey Prigogin CLA 2012-05-16 16:55:42 EDT
Parsing support for constexpr keyword has been added in commit http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=e55325538485fe691418c4b50c7a4d947239d95c.
Comment 5 Sergey Prigogin CLA 2012-12-11 23:37:06 EST
Evaluation of constexpr functions was added recently. The only remaining part is constant expressions of aggregate types.
Comment 6 CDT Genie CLA 2013-02-27 11:43:08 EST
*** cdt git genie on behalf of Sergey Prigogin ***

    Bug 332829. Parsing support for constexpr keyword. Also added few
    new C++11 keywords.

[*] http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=e55325538485fe691418c4b50c7a4d947239d95c
Comment 7 Michael Woski CLA 2013-07-05 15:39:48 EDT
Created attachment 233149 [details]
a test case that causes trouble

see inside the code for details
Comment 8 Michael Woski CLA 2013-07-05 15:44:13 EDT
could this also be related to bug 402617 ?
Comment 9 Michael Woski CLA 2013-07-05 15:45:13 EDT
(In reply to comment #8)
> could this also be related to bug 402617 ?

I meant the problem in the attached file, of course.
Comment 10 Nathan Ridge CLA 2013-07-05 18:01:58 EDT
(In reply to comment #7)
> Created attachment 233149 [details]
> a test case that causes trouble
> 
> see inside the code for details

Reduced:


constexpr int f() { return 1; }

template <int>
struct A
{
    static void g() {}
};

void bar()
{
    A<f()>::g();  // ERROR HERE: "Function 'g' could not be resolved"
}
Comment 11 Nathan Ridge CLA 2013-07-05 18:26:03 EDT
(In reply to comment #10)
> (In reply to comment #7)
> > Created attachment 233149 [details]
> > a test case that causes trouble
> > 
> > see inside the code for details
> 
> Reduced:
> 
> 
> constexpr int f() { return 1; }
> 
> template <int>
> struct A
> {
>     static void g() {}
> };
> 
> void bar()
> {
>     A<f()>::g();  // ERROR HERE: "Function 'g' could not be resolved"
> }

Seems to be a parsing problem. The "f()" in "A<f()>" is being parsed as a type-id rather than an expression.
Comment 12 Nathan Ridge CLA 2013-07-06 22:04:46 EDT
(In reply to comment #11)
> (In reply to comment #10)
> > (In reply to comment #7)
> > > Created attachment 233149 [details]
> > > a test case that causes trouble
> > > 
> > > see inside the code for details
> > 
> > Reduced:
> > 
> > 
> > constexpr int f() { return 1; }
> > 
> > template <int>
> > struct A
> > {
> >     static void g() {}
> > };
> > 
> > void bar()
> > {
> >     A<f()>::g();  // ERROR HERE: "Function 'g' could not be resolved"
> > }
> 
> Seems to be a parsing problem. The "f()" in "A<f()>" is being parsed as a
> type-id rather than an expression.

It looks like GNUCPPSourceParser.templateArgument() doesn't handle the case where a template argument could syntactically be either a type-id or a function-call-expression - it just constructs a type-id in such cases. This was probably correct in C++98, when a function-call-expression couldn't be a constant expression and thus couldn't appear in a template argument. In C++11, though, it's wrong - it should construct an ambiguous template argument, just like it does for a type-id/id-expression ambiguity.

I don't have a good enough understanding of the parser to fix this myself, I just wanted to document my investigation.
Comment 13 Michael Woski CLA 2013-10-10 13:26:39 EDT
does this fall into the same category or is this a different bug?

enum class TestEnum : int {
	E1, E2
}

template<int P>
struct A {
};

A<TestEnum::E1> a1;
Comment 14 Sergey Prigogin CLA 2013-10-10 14:17:06 EDT
(In reply to Michael Woski from comment #13)

It probably makes sense to deal with these cases one by one. Michael, could you please create a separate bug for your test case.
Comment 15 Michael Woski CLA 2013-10-10 14:32:11 EDT
(In reply to comment #14)

ok, it's in bug #419175
Comment 16 Nathan Ridge CLA 2013-12-21 01:58:37 EST
(In reply to Nathan Ridge from comment #12)
> (In reply to comment #11)
> > (In reply to comment #10)
> > > (In reply to comment #7)
> > > > Created attachment 233149 [details]
> > > > a test case that causes trouble
> > > > 
> > > > see inside the code for details
> > > 
> > > Reduced:
> > > 
> > > 
> > > constexpr int f() { return 1; }
> > > 
> > > template <int>
> > > struct A
> > > {
> > >     static void g() {}
> > > };
> > > 
> > > void bar()
> > > {
> > >     A<f()>::g();  // ERROR HERE: "Function 'g' could not be resolved"
> > > }
> > 
> > Seems to be a parsing problem. The "f()" in "A<f()>" is being parsed as a
> > type-id rather than an expression.
> 
> It looks like GNUCPPSourceParser.templateArgument() doesn't handle the case
> where a template argument could syntactically be either a type-id or a
> function-call-expression - it just constructs a type-id in such cases. This
> was probably correct in C++98, when a function-call-expression couldn't be a
> constant expression and thus couldn't appear in a template argument. In
> C++11, though, it's wrong - it should construct an ambiguous template
> argument, just like it does for a type-id/id-expression ambiguity.
> 
> I don't have a good enough understanding of the parser to fix this myself, I
> just wanted to document my investigation.

Decided to give this a shot: https://git.eclipse.org/r/#/c/20140/
Comment 17 Sergey Prigogin CLA 2014-08-25 20:02:40 EDT
Fixed by the Nathan's change.
Comment 18 Nathan Ridge CLA 2014-08-26 02:00:52 EDT
(In reply to Sergey Prigogin from comment #17)
> Fixed by the Nathan's change.

What my patch fixed was Michael's test case in comment #7.

Is the bug as a whole fixed? In particular, is the part mentioned in comment 5 ("constant expressions of aggregate types") implemented?

(In reply to Sergey Prigogin from comment #5)
> Evaluation of constexpr functions was added recently. The only remaining
> part is constant expressions of aggregate types.
Comment 19 Michael Woski CLA 2014-08-26 05:23:14 EDT
(In reply to Nathan Ridge from comment #18)

> Is the bug as a whole fixed? In particular, is the part mentioned in comment
> 5 ("constant expressions of aggregate types") implemented?

I don't know exactly what "constant expression of aggregate types" really means, but does this also cover std::enable_if templates and the likes. I'm asking because things like

class A : std::enable_if<condition,B>::type{};

do not work.
Comment 20 Michael Woski CLA 2014-08-26 09:05:30 EDT
(In reply to Michael Woski from comment #19)
> (In reply to Nathan Ridge from comment #18)
> 
> > Is the bug as a whole fixed? In particular, is the part mentioned in comment
> > 5 ("constant expressions of aggregate types") implemented?
> 
> I don't know exactly what "constant expression of aggregate types" really
> means, but does this also cover std::enable_if templates and the likes. I'm
> asking because things like
> 
> class A : std::enable_if<condition,B>::type{};
> 
> do not work.

please forget that, I messed things up. std::enable_if expressions work fine as a template parameter
Comment 21 Sergey Prigogin CLA 2014-08-26 12:56:40 EDT
(In reply to Nathan Ridge from comment #18)
> What my patch fixed was Michael's test case in comment #7.

I don't know which patch fixed the test case in comment #7, but it appears to work now.
> 
> Is the bug as a whole fixed? In particular, is the part mentioned in comment
> 5 ("constant expressions of aggregate types") implemented?

Constant expressions of aggregate types are not implemented. I've created bug 442612 to track it separately.