public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/58969] New: bogus error: the value of 'kName' is not usable in a constant expression
@ 2013-11-01 21:30 ppluzhnikov at google dot com
2014-12-10 20:29 ` [Bug c++/58969] " ville.voutilainen at gmail dot com
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: ppluzhnikov at google dot com @ 2013-11-01 21:30 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58969
Bug ID: 58969
Summary: bogus error: the value of 'kName' is not usable in a
constant expression
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: ppluzhnikov at google dot com
Google ref: b/11479502
/// --- cut ---
template <const char name[]>
class BaseObject {
virtual const char* GetName() const {
return name;
}
};
const char kName[] = "name";
class Object : public BaseObject<kName> {
};
int main() {
return 0;
}
/// --- cut ---
Using g++ (GCC) 4.9.0 20131028 (experimental)
g++ -c t.cc
t.cc:9:34: error: 'kName' cannot appear in a constant-expression
class Object : public BaseObject<kName> {
^
t.cc:9:39: error: template argument 1 is invalid
class Object : public BaseObject<kName> {
^
g++ -c t.cc -std=c++11
t.cc:9:34: error: the value of 'kName' is not usable in a constant expression
class Object : public BaseObject<kName> {
^
t.cc:8:12: note: 'kName' was not declared 'constexpr'
const char kName[] = "name";
^
Compiles with Clang.
Analysis by Richard Smith:
This is a GCC bug. It appears to be some sort of confusion in the way GCC
handles internal linkage non-type template parameters of pointer type. You can
also get GCC to accept the code by marking kName as 'extern'.
Obligatory standards references (relative to N3797):
[temp.param](14.1)/8: "A non-type template-parameter of type "array of T" [...]
is adjusted to be of type "pointer to T".
[temp.arg.nontype](14.3.2)/1: "A template-argument for a non-type, non-template
template-parameter shall be [...] a constant expression that designates the
address of a complete object with static storage duration and external or
internal linkage [...] expressed [...] as & id-expression, where the
id-expression is the name of an object [...], except that the & may be omitted
if the name refers to a[n] [...] array"
Note that "kName" is a constant expression, because it is a glvalue core
constant expression whose value refers to an object with static storage
duration (see [expr.const](5.19)/4).
[temp.arg.nontype](14.3.2)/5: "The following conversions are performed on each
expression used as a non-type template-argument. [...] For a non-type
template-parameter of type pointer to object, [...] the array-to-pointer
conversion [is] applied."
So BaseObject has a template parameter of type 'const char*', and that
parameter can bind to the template argument kName (after array-to-pointer
decay). There's no requirement that kName be declared 'constexpr'; its value is
not used here, only its address is used.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug c++/58969] bogus error: the value of 'kName' is not usable in a constant expression
2013-11-01 21:30 [Bug c++/58969] New: bogus error: the value of 'kName' is not usable in a constant expression ppluzhnikov at google dot com
@ 2014-12-10 20:29 ` ville.voutilainen at gmail dot com
2014-12-10 22:08 ` ktietz at gcc dot gnu.org
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: ville.voutilainen at gmail dot com @ 2014-12-10 20:29 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58969
Ville Voutilainen <ville.voutilainen at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |rejects-valid
Status|UNCONFIRMED |NEW
Last reconfirmed| |2014-12-10
CC| |ville.voutilainen at gmail dot com
Ever confirmed|0 |1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug c++/58969] bogus error: the value of 'kName' is not usable in a constant expression
2013-11-01 21:30 [Bug c++/58969] New: bogus error: the value of 'kName' is not usable in a constant expression ppluzhnikov at google dot com
2014-12-10 20:29 ` [Bug c++/58969] " ville.voutilainen at gmail dot com
@ 2014-12-10 22:08 ` ktietz at gcc dot gnu.org
2014-12-10 22:26 ` richard-gccbugzilla at metafoo dot co.uk
2014-12-11 10:36 ` ktietz at gcc dot gnu.org
3 siblings, 0 replies; 5+ messages in thread
From: ktietz at gcc dot gnu.org @ 2014-12-10 22:08 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58969
Kai Tietz <ktietz at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jason at gcc dot gnu.org,
| |ktietz at gcc dot gnu.org
--- Comment #1 from Kai Tietz <ktietz at gcc dot gnu.org> ---
Hmm, issue seems to be in too restrictive decl_maybe_constant_var_p function.
We could allow here additional ARRAY_TYPEs with constant, non-vla, and trivial
destructors. Maybe even non-trivial destructors could be ok. Not sure
Suggested patch, which allows provided testcase to run is:
Index: decl2.c
===================================================================
--- decl2.c (Revision 218570)
+++ decl2.c (Arbeitskopie)
@@ -4157,8 +4157,12 @@ decl_maybe_constant_var_p (tree decl)
return false;
if (DECL_DECLARED_CONSTEXPR_P (decl))
return true;
- return (CP_TYPE_CONST_NON_VOLATILE_P (type)
- && INTEGRAL_OR_ENUMERATION_TYPE_P (type));
+ if (!CP_TYPE_CONST_NON_VOLATILE_P (type))
+ return false;
+ return ((TREE_CODE (type) == ARRAY_TYPE
+ && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (type))
+ && !array_of_runtime_bound_p (type))
+ || INTEGRAL_OR_ENUMERATION_TYPE_P (type));
}
/* Complain that DECL uses a type with no linkage. In C++98 mode this is
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug c++/58969] bogus error: the value of 'kName' is not usable in a constant expression
2013-11-01 21:30 [Bug c++/58969] New: bogus error: the value of 'kName' is not usable in a constant expression ppluzhnikov at google dot com
2014-12-10 20:29 ` [Bug c++/58969] " ville.voutilainen at gmail dot com
2014-12-10 22:08 ` ktietz at gcc dot gnu.org
@ 2014-12-10 22:26 ` richard-gccbugzilla at metafoo dot co.uk
2014-12-11 10:36 ` ktietz at gcc dot gnu.org
3 siblings, 0 replies; 5+ messages in thread
From: richard-gccbugzilla at metafoo dot co.uk @ 2014-12-10 22:26 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58969
--- Comment #2 from Richard Smith <richard-gccbugzilla at metafoo dot co.uk> ---
(In reply to Kai Tietz from comment #1)
> Hmm, issue seems to be in too restrictive decl_maybe_constant_var_p function.
I don't know how the GCC code is structured, but I don't think that's right;
that function appears to be checking whether the value of the variable can be
used in a constant expression. The relevant condition here is whether the
address of the variable can be used.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug c++/58969] bogus error: the value of 'kName' is not usable in a constant expression
2013-11-01 21:30 [Bug c++/58969] New: bogus error: the value of 'kName' is not usable in a constant expression ppluzhnikov at google dot com
` (2 preceding siblings ...)
2014-12-10 22:26 ` richard-gccbugzilla at metafoo dot co.uk
@ 2014-12-11 10:36 ` ktietz at gcc dot gnu.org
3 siblings, 0 replies; 5+ messages in thread
From: ktietz at gcc dot gnu.org @ 2014-12-11 10:36 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58969
--- Comment #3 from Kai Tietz <ktietz at gcc dot gnu.org> ---
(In reply to Richard Smith from comment #2)
> (In reply to Kai Tietz from comment #1)
> > Hmm, issue seems to be in too restrictive decl_maybe_constant_var_p function.
>
> I don't know how the GCC code is structured, but I don't think that's right;
> that function appears to be checking whether the value of the variable can
> be used in a constant expression. The relevant condition here is whether the
> address of the variable can be used.
hmm, this function has nothing to do with its value. AFAIU the comment (and
its use) it just checks that a VAR-decl might be a constant.
In general it checks for const and volatile attributes, and assumes for
integral/enumeral typed variables that variable is constant.
So a 'const char *' isn't constant - as just the destination the variable is
pointing to is constant, but not the variable itself. For a constant array
with trivial destructor, and non-vla size this is different. The array's name
is indeed a constant address, and its content is constant too. Of course the a
variable pointing to into an array isn't constant, but the array itself is.
Anyway I might be wrong here
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-12-11 10:36 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-01 21:30 [Bug c++/58969] New: bogus error: the value of 'kName' is not usable in a constant expression ppluzhnikov at google dot com
2014-12-10 20:29 ` [Bug c++/58969] " ville.voutilainen at gmail dot com
2014-12-10 22:08 ` ktietz at gcc dot gnu.org
2014-12-10 22:26 ` richard-gccbugzilla at metafoo dot co.uk
2014-12-11 10:36 ` ktietz at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).