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

Incorrect constructor name resolution #8635

Closed
RealLitb mannequin opened this issue Sep 30, 2010 · 3 comments
Closed

Incorrect constructor name resolution #8635

RealLitb mannequin opened this issue Sep 30, 2010 · 3 comments
Labels
bugzilla Issues migrated from bugzilla c++ duplicate Resolved as duplicate

Comments

@RealLitb
Copy link
Mannequin

RealLitb mannequin commented Sep 30, 2010

Bugzilla Link 8263
Resolution DUPLICATE
Resolved on Jan 18, 2017 14:36
Version trunk
OS Linux
CC @DougGregor,@zygoloid

Extended Description

The following looks well-formed

struct A {
typedef A type;
};

// The following is SFINAE'ed out if T is A
template
void f(typename T::A*);

// The following is not when T is A
template
void f(typename T::type*);

int main() {
f(0);
}

Clang says

main1.cpp:14:3: error: call to 'f' is ambiguous
f(0);
^~~~
main1.cpp:7:6: note: candidate function [with T = A]
void f(typename T::A*);
^
main1.cpp:11:6: note: candidate function [with T = A]
void f(typename T::type*);
^

And the Standard says at [class.qual]p2

"In a lookup in which the constructor is an acceptable lookup result and the nested-name-specifier nominates a class C [...] if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C [...] the name is instead considered to name the constructor of class C.".

A constructor is an acceptable lookup result for a "typename ...", since function names are not ignored in a typename-specifier during lookup (see the clearifying note at p2). Clang restricts that replacement to situations where constructors can be declared only, though.

The above code is accepted by comeau online compiler. Usually I found GCC rejects all the cases I expect it to for the constructor name replacement (i.e it acts not like clang in this regard), but GCC also rejects the above code. But that is because GCC ignores function names in a typename-specifier lookup, not because it wouldn't do the constructor-name replacement in general.

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 1, 2014

testcase.cpp

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 1, 2014

template<class T>
struct A { };

int main () {
  A<int>::A        a; // ill-formed, inaccurately accepted
  A<int>::A<float> b; // ill-formed, inaccurately accepted
}

The above snippet is a reduced testcase for what Johannes Schaub has explained.

We shall not be able to write A<int>::A x; (because A<int>::A would denote the constructor of A<int>, not the type itself).

Likewise, A<int>::A<float> y; shall not compile (for the same reason); A<int>::A denotes the constructor, not the injected-class-name acting as a template-id.

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented Jan 18, 2017

*** This bug has been marked as a duplicate of bug llvm/llvm-bugzilla-archive#13403 ***

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 3, 2021
Michael137 pushed a commit to Michael137/llvm-project that referenced this issue Apr 30, 2024
Reapply "[llvm] Fix assertion error where we didn't check fixed point…
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c++ duplicate Resolved as duplicate
Projects
None yet
Development

No branches or pull requests

1 participant