Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[basic.lookup.argdep] should also perform if function declaration is not found #5209

Open
xmh0511 opened this issue Jan 15, 2022 · 4 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Jan 15, 2022

[basic.lookup.argdep] p1 says

When the postfix-expression in a function call ([expr.call]) is an unqualified-id, and unqualified lookup ([basic.lookup.unqual]) for the name in the unqualified-id does not find any

This implies/asserts that the unqualified name lookup at least finds one function or function template declaration because [expr.call] p1 says that:

A function call is a postfix expression followed by parentheses containing a possibly empty, comma-separated list of initializer-clauses which constitute the arguments to the function. The postfix expression shall have function type or function pointer type.

In other words, if the postfix expression is not of function type or function pointer type, "a postfix expression followed by parentheses..." cannot be considered as a function call(e.g., Explicit type conversion (functional notation)).

Consider this exmple:

namespace A{
    namespace B{
        struct X{};
        void fun(X,char);
    }
    void invoke(){
        fun(B::X{},0);  // #1
    }
}

The unqualified name lookup for fun at #1 will find nothing however ADL can find the function declaration in A::B. Should we say that?

After an unqualified lookup performs for an expression that has a form:

postfix-expression ( expression-listopt )

where postfix-expression is an unqualified-id and the result of the unqualified lookup ([basic.lookup.unqual]) for the name does not include any:

  • declaration of a class member, or and
  • function declaration inhabiting a block scope, or and
  • declaration not of a function or function template

then lookup for the name also includes the result of argument-dependent lookup in a set of associated namespaces that depends on the types of the arguments (and for template template arguments, the namespace of the template argument), as specified below.

Seems that the "or" in the original list should be removed and should be replaced with "and" instead. Actually, only all bullets are satisfied will ADL perform for that name. However, "or" sounds like that merely needs one of the bullets to be satisfied. Also, we should admit that ADL only performs for an unqualified name after the unqualified name lookup has been completed and only if the result of that unqualified name lookup does not violate the above bullets.

namespace A{
    namespace B{
        struct X{};
        void fun(X,char);
    }
    void fun();  // #1
    struct fun{};  // #2
    void invoke(){
        fun(B::X{},0);  
    }
}

In this example, unqualified name lookup does find the class definition at #2, merely, it is discarded from the result. So, we say "the result of the unqualified lookup ([basic.lookup.unqual]) for the name does not include any..." seems to be clearer.

@languagelawyer
Copy link
Contributor

After an unqualified lookup performs for an expression that has a form: … where postfix-expression is an unqualified-id

Same logic as in the start of the (non-)issue description can be applied here: «for an expression» implies/asserts that the lookup has already been performed and we know that we have a postfix-expression, and not, say, typename-specifier, before (.
The standard need not define the algorithm for an implementation how to look at the code during the intermediate stages of parsing.

Actually, only all bullets are satisfied will ADL perform for that name.

Your rewrite, ignoring weird use of «any» and «all» together, means (among other things) that one needs to find a block declaration of a function which is a declaration of not a function at the same time.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Jan 17, 2022

Same logic as in the start of the (non-)issue description can be applied here: «for an expression» implies/asserts that the lookup has already been performed and we know that we have a postfix-expression, and not, say, typename-specifier

You're right. I was aware of that issue, however, declaration not of a function or function template has announced that the unqualified-id cannot be a type entity. This part is similar to this issue #4791. Maybe, we should introduce unqualified-name in the same manner as that in that issue.

The standard need not define the algorithm for an implementation how to look at the code during the intermediate stages of parsing.

It's not true, since [basic.lookup.general] says that:

Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the semantic properties introduced by the declarations used in further processing.

This means that a grammar component relying on the properties of a declaration is checked after the name lookup has determined what the declaration is(e.g., whether the name denotes a type or other entities, which will determine whether the expression is a function call or a explicit type conversion).

@languagelawyer
Copy link
Contributor

[basic.lookup.general] says that:

Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the semantic properties introduced by the declarations used in further processing.

Doesn't this mean that

The postfix expression shall have function type or function pointer type.

is checked after lookup and there is no problem in saying

When the postfix-expression in a function call

@xmh0511
Copy link
Contributor Author

xmh0511 commented Jan 21, 2022

Doesn't this mean that

The postfix expression shall have function type or function pointer type.

is checked after lookup and there is no problem in saying

When the postfix-expression in a function call

The key point here is that a normal unqualified name lookup does not yet find any declaration for the name. At this point, we don't know what the entity that name denotes since we cannot associate the name with any declaration. Then, ADL should also perform for this name, but as aforementioned, we cannot say the name definitely denotes a function, at least before ADL finds any declaration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants