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

-fms-compatibility should diagnose failed lookups in the presence of a dependent base #16386

Closed
rnk opened this issue May 15, 2013 · 6 comments
Closed
Labels
bugzilla Issues migrated from bugzilla clang:frontend Language frontend issues, e.g. anything involving "Sema"

Comments

@rnk
Copy link
Collaborator

rnk commented May 15, 2013

Bugzilla Link 16014
Resolution FIXED
Resolved on Oct 21, 2013 11:08
Version unspecified
OS Windows NT
Attachments minimal dependent base lookup failure test case
CC @zygoloid,@timurrrr

Extended Description

This is a variation on the old "unqualified lookup in dependent base" problem. Normally clang errors out on code like the following, but in -fms-compatibility mode, it fails to instantiate the method and actually makes it to codegen without crashing or erroring out. Eventually I get a link error because nobody else creates this instantiation.

$ cat min_etw.cc
template struct DepBase {
int header; // Commenting out gives the same result with -fms-compatibility.
};
template struct Depends : public DepBase {
int *get() { return &header; } // header does not resolve
};
int *foo() {
Depends<5> event;
return event.get();
}

$ clang -cc1 -fms-extensions -triple i686-pc-linux min_etw.cc -emit-llvm -o t.ll
min_etw.cc:4:25: error: use of undeclared identifier 'header'
void *get() { return &header; } // header does not resolve
^
1 error generated.

This is correct, it's part of the FAQ:

http://clang.llvm.org/compatibility.html#dep_lookup_bases

$ clang -cc1 -fms-compatibility -triple i686-pc-linux min_etw.cc -emit-llvm -o t.ll

Exit code 0 and no diagnostic.

$ grep '_Z.get' t.ll
%call = call i32
@​_ZN7DependsILi5EE3getEv(%struct.Depends* %event)
declare i32* @​_ZN7DependsILi5EE3getEv(%struct.Depends*) #​1

get is declared, not defined.

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented May 15, 2013

I would have expected msvc to accept that code (with 'header' uncommented). Does it not?

@rnk
Copy link
Collaborator Author

rnk commented May 15, 2013

Yes, it accepts it. There's two bugs:

  1. If delayed name lookup fails, there should be a diagnostic, not a silent failure to instantiate leading to link errors.

  2. If delayed name lookup succeeds, then we should instantiate the method.

I haven't looked, but my guess is that the delayed dependent base lookup is unimplemented in some way.

For my immediate problem, I just fixed the code, but a diagnostic would be good.

@rnk
Copy link
Collaborator Author

rnk commented Oct 11, 2013

I hit this again and debugged it all over from scratch. Clearly I should've fixed it the first time. :)

This bug only occurs when you take the address of a member of a dependent base. This test case fails to link because we fail to instantiate get2 and we fail to emit a diagnostic.

struct A { int a; };
template struct B : T {
int get() { return a; }
int *get2() { return &a; }
};
int main() {
B b;
b.get();
b.get2();
}

The AST shows shows that the instantiation of get2 is an invalid decl, while get() is fine.

There are two codepaths in ActOnDependentIdExpression, one for addressof and one for not, and perhaps in this instance we should be taking the first code path.

@rnk
Copy link
Collaborator Author

rnk commented Oct 14, 2013

Richard came up with this testcase offline:

template
struct Foo : T {
struct Bar {
int baz() { return a; } // MSVC finds A::a
};
};
struct A { static const int a = 1; };
int main() {
Foo::Bar b;
return b.baz();
}
int a = 0; // clang finds ::a.

For full compatibility, we'd need to add a new AST node for all unqualified ids in templates that delays lookup until instantiation time, essentially removing the last vestiges of two-phase name lookup from -fms-compatibility. Note that this node could also be useful during error recovery if lookup fails in a class template with dependent bases.

The question is, do we want to go this far?

Personally, I'd like to warn on this extension. If we assume most of our users make their code -Wmicrosoft clean, then it doesn't make much sense to maintain this highly divergent code path for template parsing. So I'd like to try to get by with the current solution of turning failed lookups into CXXDependentScopeMemberExprs. Does that seem reasonable?

@rnk
Copy link
Collaborator Author

rnk commented Oct 21, 2013

Fixed by r192860 by assuming unknown unqualified ids are dependent member exprs and without doing fully delayed lookup.

@rnk
Copy link
Collaborator Author

rnk commented Nov 26, 2021

mentioned in issue llvm/llvm-bugzilla-archive#18714

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 4, 2021
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 clang:frontend Language frontend issues, e.g. anything involving "Sema"
Projects
None yet
Development

No branches or pull requests

1 participant