Bug 10479 - alignof and sizeof (and other expressions) in attributes does not compile inside template classes
Summary: alignof and sizeof (and other expressions) in attributes does not compile ins...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.0
: P3 normal
Target Milestone: 4.0.0
Assignee: Giovanni Bajo
URL:
Keywords: patch, rejects-valid
Depends on:
Blocks: 8670
  Show dependency treegraph
 
Reported: 2003-04-24 12:16 UTC by Richard Biener
Modified: 2004-10-16 18:16 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2004-08-04 06:05:15


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2003-04-24 12:16:01 UTC
__alignof__(double) or any other not-dependend type is rejected as being not compile-time constant in a template class. Like:

template <int i>
struct foo2 {
        float bar __attribute__((aligned(__alignof__(double))));
};

while in a non-template context (just omit the template <int i> from the above example), it is accepted. Also specifying 8 rather than __alignof__(double) is ok.

bellatrix:~/src/tests$ g++ -c attribute.cpp 
attribute.cpp:7: requested alignment is not a constant

While of course __alignof__ is a gnu extension this behavior may be "correct", but it is surely not what one would expect and undocumented.

Release:
from 2.95 throughout 3.4

Environment:
ia32 linux-gnu
Comment 1 Richard Biener 2003-04-24 12:16:01 UTC
Fix:
A workaorund is to use a configure check for the alignment and create a #define for the actual constant.
Comment 2 Wolfgang Bangerth 2003-04-24 13:47:51 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed.
Comment 3 Richard Biener 2004-09-14 13:09:46 UTC
Same with using sizeof() instead of __alignof__.  Can we please clarify if we
are supporting this syntax?  It seems at least that sizeof() is a constant
expression
in the sense of the C++ standard.  So - are we supposed to support any
conforming constant expression as argument to attribute(aligned)?

I'd like to CC a C++ maintainer here, but it seems just for one comment I cannot
do this, so, Mark added to PR CC list.

Thanks,
Richard.
Comment 4 Gabriel Dos Reis 2004-09-14 14:46:29 UTC
Subject: Re:  __alignof__(double) not compile time constant inside template class

"rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| Same with using sizeof() instead of __alignof__.  Can we please clarify if we

You'e right.  The issue has nothing to do with __alignof__ extension.
Using sizeof is probably better.

| are supporting this syntax?  It seems at least that sizeof() is a constant
| expression
| in the sense of the C++ standard.  So - are we supposed to support any
| conforming constant expression as argument to attribute(aligned)?
| 
| I'd like to CC a C++ maintainer here, but it seems just for one comment I cannot
| do this, so, Mark added to PR CC list.


I know (or at least I knew) what is going on here.  
I was meaning to send a detailed explanation of this to the general
list a long time ago.  We have another instance of this bug somewhere,
I tink.

The executive summary is that __attribute__ was designed to ignore
language lookup rules -- yep, lookup!

When parsing attributes, the parser interprets any identifier (or
anything that looks so) as an attribute name/value or keyword.  In
particular, it does not understand symbolic constants.  It it is
expecting to see a constant expression, then it really means a
literal or combination of such; but not computed constant expressions
or symbolic constant expressions.  That is just plain stupid but it
works for C, and that is what they were designed for.
Given the above situation, tsubst() does not even try to look into
attributes -- because there is no much it would do there since
attributes disobey language scope rules.

To solve, this problem, one would have to redesign the name lookup
rules for attributes.  Or/and provide an "escaping" mechanism for the
compiler to follow usual language rules.

-- Gaby
Comment 5 Richard Biener 2004-09-14 14:51:37 UTC
Subject: Re:  __alignof__(double) not compile time constant
 inside template class

> To solve, this problem, one would have to redesign the name lookup
> rules for attributes.  Or/and provide an "escaping" mechanism for the
> compiler to follow usual language rules.

Does this "match" with that it works for non-template classes? I.e.

struct foo2 {
        float bar __attribute__((aligned(__alignof__(double))));
};

just works.  Remember that "double" is not a dependent type - I would
certainly understand that using a dependent type would not work (or
would be harder to do).  But not allowing non-dependent types in template
classes doesn't look difficult (from a users point of view), are they?

Thanks for trying to explain,

Richard.

Comment 6 Gabriel Dos Reis 2004-09-14 15:05:40 UTC
Subject: Re:  __alignof__(double) not compile time constant inside template class

"rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| ------- Additional Comments From rguenth at tat dot physik dot uni-tuebingen dot de  2004-09-14 14:51 -------
| Subject: Re:  __alignof__(double) not compile time constant
|  inside template class
| 
| > To solve, this problem, one would have to redesign the name lookup
| > rules for attributes.  Or/and provide an "escaping" mechanism for the
| > compiler to follow usual language rules.
| 
| Does this "match" with that it works for non-template classes? I.e.
| 
| struct foo2 {
|         float bar __attribute__((aligned(__alignof__(double))));
| };
| 
| just works.  Remember that "double" is not a dependent type - I would

I know "double" is not dependent type.  Did you doubt that?

As I said, attributes are implemented in a way that defy language rules.  
Inside, templates, it is even worse. And tsubst() does not even look there.  

Try

     const int N = 4;

     struct S {
        enum { M = 4 };
        float ahar __attribute__((aligned(N)));
        float bhar __attribute__((aligned(M)));
     };


| certainly understand that using a dependent type would not work (or
| would be harder to do).  But not allowing non-dependent types in template
| classes doesn't look difficult (from a users point of view), are they?

Do you believe I'm against making this work?  I find it very annoying,
and happen to qualify as plain stupid.  I was just explaining what was
going on.  

Some time ago, I tried to fix that but it blew up.  It may probably be
not difficult, but it you don't try you probably won't figure it out.

-- Gaby
Comment 7 Richard Biener 2004-09-14 15:11:31 UTC
Subject: Re:  __alignof__(double) not compile time constant
 inside template class

On 14 Sep 2004, gdr at integrable-solutions dot net wrote:

> I know "double" is not dependent type.  Did you doubt that?

No, I thought you maybe missed it.  I thought so because I cannot
see the difference between the templated and non-templated variant
- of course just because of my ignorance.

> Do you believe I'm against making this work?  I find it very annoying,
> and happen to qualify as plain stupid.  I was just explaining what was
> going on.

Ok thanks, I'll guess target-milestone would be 4.1 earliest then.

> Some time ago, I tried to fix that but it blew up.  It may probably be
> not difficult, but it you don't try you probably won't figure it out.

Of course.

Richard.

Comment 8 Giovanni Bajo 2004-10-16 02:01:36 UTC
Patch submitted:
http://gcc.gnu.org/ml/gcc-patches/2004-10/msg01319.html
Comment 9 Mark Mitchell 2004-10-16 03:38:27 UTC
Subject: Re:  __alignof__(double) not compile time constant
 inside template class

giovannibajo at libero dot it wrote:

>------- Additional Comments From giovannibajo at libero dot it  2004-10-16 02:01 -------
>Patch submitted:
>http://gcc.gnu.org/ml/gcc-patches/2004-10/msg01319.html
>  
>
OK.

Comment 10 GCC Commits 2004-10-16 11:05:10 UTC
Subject: Bug 10479

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	giovannibajo@gcc.gnu.org	2004-10-16 11:04:59

Modified files:
	gcc/cp         : ChangeLog parser.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/ext: attrib16.C 

Log message:
	PR c++/10479
	* parser.c (cp_parser_parenthesized_expression_list): Fold
	non-dependent expressions in attribute lists.
	
	PR c++/10479
	* g++.dg/ext/attrib16.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4439&r2=1.4440
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/parser.c.diff?cvsroot=gcc&r1=1.264&r2=1.265
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4461&r2=1.4462
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/attrib16.C.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 11 Giovanni Bajo 2004-10-16 11:06:24 UTC
Fixed in GCC 4.0.0. Thanks for your report!
Comment 12 Richard Biener 2004-10-16 15:42:58 UTC
Subject: Re:  alignof and sizeof (and other expressions) in
 attributes does not compile inside template classes

giovannibajo at libero dot it wrote:
> ------- Additional Comments From giovannibajo at libero dot it  2004-10-16 11:06 -------
> Fixed in GCC 4.0.0. Thanks for your report!

Can this be trivially backported to 3.4?  That would be cool.

Thanks,
Richard.

Comment 13 Giovanni Bajo 2004-10-16 18:16:48 UTC
There are good chances that this can be easily backported to 3.4. On the other 
hand, this is not a regression, so you will need to talk Mark into doing it. I 
can easily test and commit the patch also there, if Mark agrees.