-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[clang] Fix conflicting declaration error with using_if_exists #167646
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
base: main
Are you sure you want to change the base?
Changes from all commits
c9a70b4
fce8e55
a8ca3db
b2a5767
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,7 @@ | |
| #include "clang/AST/EvaluatedExprVisitor.h" | ||
| #include "clang/AST/Expr.h" | ||
| #include "clang/AST/ExprCXX.h" | ||
| #include "clang/AST/GlobalDecl.h" | ||
| #include "clang/AST/RecordLayout.h" | ||
| #include "clang/AST/StmtVisitor.h" | ||
| #include "clang/AST/TypeLoc.h" | ||
|
|
@@ -12832,6 +12833,15 @@ bool Sema::CheckUsingShadowDecl(BaseUsingDecl *BUD, NamedDecl *Orig, | |
| (isa_and_nonnull<UnresolvedUsingIfExistsDecl>(NonTag))) { | ||
| if (!NonTag && !Tag) | ||
| return false; | ||
|
|
||
| // Only report the error if this using_if_exists decl can be a | ||
| // substitute for the original decl. LookupResult will find things with | ||
| // the same name but we also want to take into account namespaces and | ||
| // other scopes. GlobalDecl helps take care of that. | ||
| NamedDecl *UsedTag = NonTag ? NonTag : Tag; | ||
| if (GlobalDecl(Target) != GlobalDecl(UsedTag)) | ||
| return false; | ||
|
|
||
| Diag(BUD->getLocation(), diag::err_using_decl_conflict); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this error ever emitted now? |
||
| Diag(Target->getLocation(), diag::note_using_decl_target); | ||
| Diag((NonTag ? NonTag : Tag)->getLocation(), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -521,11 +521,15 @@ void LookupResult::resolveKind() { | |
|
|
||
| llvm::SmallVector<const NamedDecl *, 4> EquivalentNonFunctions; | ||
| llvm::BitVector RemovedDecls(N); | ||
| llvm::BitVector UnresolvedUsingDecls(N); | ||
|
|
||
| for (unsigned I = 0; I < N; I++) { | ||
| const NamedDecl *D = Decls[I]->getUnderlyingDecl(); | ||
| D = cast<NamedDecl>(D->getCanonicalDecl()); | ||
|
|
||
| if (isa<UnresolvedUsingIfExistsDecl>(D)) | ||
| UnresolvedUsingDecls.set(I); | ||
|
|
||
| // Ignore an invalid declaration unless it's the only one left. | ||
| // Also ignore HLSLBufferDecl which not have name conflict with other Decls. | ||
| if ((D->isInvalidDecl() || isa<HLSLBufferDecl>(D)) && | ||
|
|
@@ -633,17 +637,24 @@ void LookupResult::resolveKind() { | |
| getSema().diagnoseEquivalentInternalLinkageDeclarations( | ||
| getNameLoc(), HasNonFunction, EquivalentNonFunctions); | ||
|
|
||
| if ((HasNonFunction && (HasFunction || HasUnresolved)) || | ||
| (HideTags && HasTag && (HasFunction || HasNonFunction || HasUnresolved))) | ||
|
Comment on lines
+640
to
+641
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be possible to add a comment explaining each case in this condition?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one was existing code that was moved so I'm not entirely sure what the intended logic was behind this. The primary thing I cared about was if this led to an ambiguous lookup. |
||
| Ambiguous = true; | ||
|
|
||
| if (Ambiguous && UnresolvedUsingDecls.count()) { | ||
| // If we would have an ambiguous reference but any of them are | ||
| // using_if_exist decls, ignore them since they are unresolved. | ||
| RemovedDecls |= UnresolvedUsingDecls; | ||
| Ambiguous = false; | ||
| } | ||
|
|
||
| // Remove decls by replacing them with decls from the end (which | ||
| // means that we need to iterate from the end) and then truncating | ||
| // to the new size. | ||
| for (int I = RemovedDecls.find_last(); I >= 0; I = RemovedDecls.find_prev(I)) | ||
| Decls[I] = Decls[--N]; | ||
| Decls.truncate(N); | ||
|
|
||
| if ((HasNonFunction && (HasFunction || HasUnresolved)) || | ||
| (HideTags && HasTag && (HasFunction || HasNonFunction || HasUnresolved))) | ||
| Ambiguous = true; | ||
|
|
||
| if (Ambiguous && ReferenceToPlaceHolderVariable) | ||
| setAmbiguous(LookupAmbiguityKind::AmbiguousReferenceToPlaceholderVariable); | ||
| else if (Ambiguous) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, how exactly
GlobalDeclhelps here?I see it simply stores a pointer, say for a
FunctionDecl. It is not asking for a canonical decl and then its operator==which is used by!=operator compares the stored pointers.