[RFD] Are enums allowed to capture local const variables?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[RFD] Are enums allowed to capture local const variables?

Kristof Beyls via cfe-dev
Hi all,

The following code snippet will compile with GCC, but not with LLVM:

constexpr unsigned g(const float *) { return 3; }
unsigned f() {
  const float x[] = {1.0};
  enum  { SIZE = g(x) };
  return SIZE;
}

At first glance, this looks fine to me, as the expression in the assignment is a constexpr function call with a const parameter.
Clang however errors with "reference to local variable 'x' declared in enclosing function".

I traced this down to the function getParentOfCapturingContextOrNull in SemaExpr.cpp, which will diagnose the variable reference uncapturable if it does not appear in a block literal, captured statement, or lambda expression.

My question is: Why does this list not contain enum declarations, at least if the declaration is local and the variable is in the same scope?

I tried to find a mention of this in the C++ standard, but did not succeed so far.
If this is a bug I'm happy to file it on bugzilla, but I first wanted to ask what the opinions are on whether this code should be valid or not.

Kind regards,
Anna

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [RFD] Are enums allowed to capture local const variables?

Kristof Beyls via cfe-dev

For something to be a constant expression, it has to (going by C++17 section 8.20 [expr.const])

* be a core constant expression, which includes all of the subexpressions being core constant expressions (see paragraph 2)

* satisfy certain constraints in paragraph 5

Here the expression x isn’t a core constant expression because x isn’t constexpr (see paragraph 2.7.2).

(GCC will actually give an error here if the pointer argument of g is dereferenced.)

 

However even if you declare x as constexpr we still get an error. I think this part is a bug in clang – if

x is declared constexpr then the x in g(x) isn’t a constant expression (according to paragraph 5.2 it has

to have static storage duration) but that doesn’t matter because g(x) is. Or in other words, I think that

for a constexpr function call to be an actual constant expression it has to have arguments that are core

constant expressions, but they do not need to be constant expressions.

 

John

 

From: cfe-dev [mailto:[hidden email]] On Behalf Of Anna Welker via cfe-dev
Sent: 17 October 2019 18:01
To: via cfe-dev
Subject: [cfe-dev] [RFD] Are enums allowed to capture local const variables?

 

Hi all,

 

The following code snippet will compile with GCC, but not with LLVM:

 

constexpr unsigned g(const float *) { return 3; }

unsigned f() {

  const float x[] = {1.0};

  enum  { SIZE = g(x) };

  return SIZE;

}

 

At first glance, this looks fine to me, as the expression in the assignment is a constexpr function call with a const parameter.

Clang however errors with "reference to local variable 'x' declared in enclosing function".

 

I traced this down to the function getParentOfCapturingContextOrNull in SemaExpr.cpp, which will diagnose the variable reference uncapturable if it does not appear in a block literal, captured statement, or lambda expression.

 

My question is: Why does this list not contain enum declarations, at least if the declaration is local and the variable is in the same scope?

 

I tried to find a mention of this in the C++ standard, but did not succeed so far.

If this is a bug I'm happy to file it on bugzilla, but I first wanted to ask what the opinions are on whether this code should be valid or not.

 

Kind regards,

Anna


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev