[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