[cfe-dev] More Vexing Than the Most Vexing Parse; Clang Parser Bug?

Richard Smith richard at metafoo.co.uk
Tue Jul 10 22:00:56 PDT 2012

On Tue, Jul 10, 2012 at 8:14 PM, John McCall <rjmccall at apple.com> wrote:

> On Jul 10, 2012, at 7:07 PM, Seth Cantrell wrote:
> > I'm trying to figure out against whom to file a bug.
> >
> > This code is parsed differently between Clang, VC++, Comeau, and GCC.
> >
> > struct A {
> >    A() {}
> >    A(int) {}
> > };
> >
> > struct B : A {
> >    void init(int i);
> > };
> >
> > void B::init(int i) {
> >  {
> >    A::A(i); // what is this supposed to parse as?
> >  }
> > }
> >
> > int main() {
> >    B b;
> >    b.init(2);
> > }
> >
> > Clang and an earlier version of GCC parse it a variable declaration,
> Comeau and current gcc parse it as an illegal constructor call (but since
> it's illegal is that constructor really "an acceptable lookup result"
> according to ยง3.4.3.1/2?), and VC++ seems to parse it as constructing a
> temporary (which it seems hard to fathom how because if A::A is a
> constructor name then it's not legal to call and does not 'return' a
> temporary object, but if A::A is a type name then this is a variable
> declaration).
> The standard doesn't precisely define "acceptable lookup result", but I
> think (given the example in the immediate context of an
> elaborated-type-specifier) that an acceptable lookup result is one which is
> not ignored by the kind of lookup being performed.

Core issue 1310 covers this unfortunately-unclear wording. One problem with
the current statement of the rule is that we must perform two different
kinds of lookup: we must look A::A up as a simple-type-specifier in case
it's a decl-specifier, and we must look it up as a qualified-id in case
there is no decl-specifier-seq. For the former lookup, a constructor is
(presumably) not an acceptable lookup result, but core issue 147 strongly
suggests that the intention was that the lookup should find the constructor
anyway for that case.

> clang is just failing to apply the rule that this is really a reference to
> the constructor.  In fact, I'm not sure we implement that rule at all.

We do: look for err_out_of_line_type_names_constructor. It seems that
whoever implemented that interpreted "constructor is an acceptable lookup
result" as meaning "appears somewhere a constructor could be declared". We
reject this, for instance:

struct S {}; S::S(i);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120710/c11171c0/attachment.html>

More information about the cfe-dev mailing list