-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Comments
I would have expected msvc to accept that code (with 'header' uncommented). Does it not? |
Yes, it accepts it. There's two bugs:
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. |
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; }; 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. |
Richard came up with this testcase offline: template 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? |
Fixed by r192860 by assuming unknown unqualified ids are dependent member exprs and without doing fully delayed lookup. |
mentioned in issue llvm/llvm-bugzilla-archive#18714 |
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.
The text was updated successfully, but these errors were encountered: