[cfe-dev] Bug in the handling of __extension__ when instantiating template.

Enea Zaffanella zaffanella at cs.unipr.it
Mon Aug 2 05:32:31 PDT 2010


Afawct, the __extension__ keyword is partially supported by clang:
it is fully supported for expressions, where we do have a representation 
for __extension__ as a unary operator;
it is only partially supported for declarations, where no AST 
representation of the keyword is provided (rather, the parser state is 
changed when seeing the keyword and restored at the appropriate time).

We though this was enough for all clang clients except those working at 
the source code level ... but then we found the following testcase 
(coming from gcc), showing that spurious warnings can still arise:

======================================
$ cat extension.cc
void ordinary_function(int dimension)
{
     __extension__ int data[dimension];
}

template<typename T>
void template_function(int dimension)
{
     __extension__ int data[dimension];
}

template void template_function<void>(int);
======================================

When parsing the template instantiation, a warning is generated because 
the primary template does not remember that it parsed keyword __extension__:

======================================
$ clang++ -pedantic -fsyntax-only extension.cc
extension.cc:9:27: warning: variable length arrays are a C99 feature, 
accepted
       as an extension [-Wvla]
     __extension__ int data[dimension];
                           ^
extension.cc:12:15: note: in instantiation of function template 
specialization
       'template_function<void>' requested here
template void template_function<void>(int);
               ^
1 warning generated.
======================================

The following variant should be considered too, where the __extension__ 
keyword does not occur at all in the primary template:

======================================
$ cat extension2.cc
__extension__ namespace N {

void ordinary_function(int dimension)
{
     int data[dimension];
}

template<typename T>
void template_function(int dimension)
{
     int data[dimension];
}

template void template_function<void>(int);

} // namespace
======================================

As far as the representation of the __extension__ info is concerned, the 
base Decl class for AST nodes could allow for a couple of boolean flags:

   bool ExtensionWritten : 1;
   bool ExtensionSet : 1;

The first one is syntactic info that will be mainly useful for pretty 
printing and other source-level activities.

The second one is the semantic info that should be actually used to 
control the disabling of extension warnings.

It may be argued that the second flag is not actually needed, since it 
can be computed by walking up the chain of DeclContext's looking for an 
containing ExtensionWritten flag that is set. This might be a viable 
option, considering that these chains are usually short and (afaict) the 
walking up has to be performed only when starting the instantiation of a 
template.

If any of the reasoning above makes some sense, then we hope some clang 
guru is around and has great ideas for the best way to properly 
initialize these flags during parsing ...

Cheers,
Enea.



More information about the cfe-dev mailing list