Skip to content

[clang] odr-checker fix for conversion operators #146153

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ Improvements to Clang's diagnostics
false positives in exception-heavy code, though only simple patterns
are currently recognized.


Improvements to Clang's time-trace
----------------------------------

Expand Down Expand Up @@ -734,7 +734,7 @@ Bug Fixes in This Version
- Fixed incorrect token location when emitting diagnostics for tokens expanded from macros. (#GH143216)
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
- Fixed a crash when a malformed using declaration appears in a ``constexpr`` function. (#GH144264)
- Fixed a bug when use unicode character name in macro concatenation. (#GH145240)
- Fixed a bug when use unicode character name in macro concatenation. (#GH145240)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -892,6 +892,7 @@ Bug Fixes to AST Handling
- Fixed a malformed printout of ``CXXParenListInitExpr`` in certain contexts.
- Fixed a malformed printout of certain calling convention function attributes. (#GH143160)
- Fixed dependency calculation for TypedefTypes (#GH89774)
- The ODR checker now correctly hashes the names of conversion operators. (#GH143152)
- Fixed the right parenthesis source location of ``CXXTemporaryObjectExpr``. (#GH143711)

Miscellaneous Bug Fixes
Expand Down
10 changes: 8 additions & 2 deletions clang/include/clang/AST/ODRHash.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,13 @@ class ODRHash {
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS);
void AddDependentTemplateName(const DependentTemplateStorage &Name);
void AddTemplateName(TemplateName Name);
void AddDeclarationName(DeclarationName Name, bool TreatAsDecl = false);
void AddDeclarationNameInfo(DeclarationNameInfo NameInfo,
bool TreatAsDecl = false);
void AddDeclarationName(DeclarationName Name, bool TreatAsDecl = false) {
AddDeclarationNameInfo(DeclarationNameInfo(Name, SourceLocation()),
TreatAsDecl);
}

void AddTemplateArgument(TemplateArgument TA);
void AddTemplateParameterList(const TemplateParameterList *TPL);

Expand All @@ -108,7 +114,7 @@ class ODRHash {
static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent);

private:
void AddDeclarationNameImpl(DeclarationName Name);
void AddDeclarationNameInfoImpl(DeclarationNameInfo NameInfo);
};

} // end namespace clang
Expand Down
29 changes: 19 additions & 10 deletions clang/lib/AST/ODRHash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,21 @@ void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {
ID.AddString(II->getName());
}

void ODRHash::AddDeclarationName(DeclarationName Name, bool TreatAsDecl) {
void ODRHash::AddDeclarationNameInfo(DeclarationNameInfo NameInfo,
bool TreatAsDecl) {
if (TreatAsDecl)
// Matches the NamedDecl check in AddDecl
AddBoolean(true);

AddDeclarationNameImpl(Name);
AddDeclarationNameInfoImpl(NameInfo);

if (TreatAsDecl)
// Matches the ClassTemplateSpecializationDecl check in AddDecl
AddBoolean(false);
}

void ODRHash::AddDeclarationNameImpl(DeclarationName Name) {
void ODRHash::AddDeclarationNameInfoImpl(DeclarationNameInfo NameInfo) {
DeclarationName Name = NameInfo.getName();
// Index all DeclarationName and use index numbers to refer to them.
auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size()));
ID.AddInteger(Result.first->second);
Expand Down Expand Up @@ -85,17 +87,18 @@ void ODRHash::AddDeclarationNameImpl(DeclarationName Name) {
}
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
AddQualType(Name.getCXXNameType());
case DeclarationName::CXXConversionFunctionName:
if (auto *TSI = NameInfo.getNamedTypeInfo())
AddQualType(TSI->getType());
else
AddQualType(Name.getCXXNameType());
break;
case DeclarationName::CXXOperatorName:
ID.AddInteger(Name.getCXXOverloadedOperator());
break;
case DeclarationName::CXXLiteralOperatorName:
AddIdentifierInfo(Name.getCXXLiteralIdentifier());
break;
case DeclarationName::CXXConversionFunctionName:
AddQualType(Name.getCXXNameType());
break;
case DeclarationName::CXXUsingDirective:
break;
case DeclarationName::CXXDeductionGuideName: {
Expand Down Expand Up @@ -314,7 +317,10 @@ class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
}

void VisitNamedDecl(const NamedDecl *D) {
Hash.AddDeclarationName(D->getDeclName());
if (const auto *FD = dyn_cast<FunctionDecl>(D))
Hash.AddDeclarationNameInfo(FD->getNameInfo());
else
Hash.AddDeclarationName(D->getDeclName());
Inherited::VisitNamedDecl(D);
}

Expand Down Expand Up @@ -828,7 +834,10 @@ void ODRHash::AddDecl(const Decl *D) {
return;
}

AddDeclarationName(ND->getDeclName());
if (auto *FD = dyn_cast<FunctionDecl>(D))
AddDeclarationNameInfo(FD->getNameInfo());
else
AddDeclarationName(ND->getDeclName());

// If this was a specialization we should take into account its template
// arguments. This helps to reduce collisions coming when visiting template
Expand Down Expand Up @@ -1017,7 +1026,7 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
}

void VisitDecltypeType(const DecltypeType *T) {
AddStmt(T->getUnderlyingExpr());
Hash.AddStmt(T->getUnderlyingExpr());
VisitType(T);
}

Expand Down
23 changes: 23 additions & 0 deletions clang/test/Modules/odr_hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5164,6 +5164,29 @@ namespace A {
A::X x;
#endif

namespace TemplateDecltypeOperator {

#if defined(FIRST) || defined(SECOND)
template <class T6>
T6 func();
#endif

#if defined(SECOND)
template <class UnrelatedT>
using UnrelatedAlias = decltype(func<UnrelatedT>())();
#endif

#if defined(FIRST) || defined(SECOND)
class A {
template <class T6>
operator decltype(func<T6>()) () {}
};
#else
A a;
#endif

}

// Keep macros contained to one file.
#ifdef FIRST
#undef FIRST
Expand Down
Loading