Skip to content

Commit c5f95e9

Browse files
committed
[clang] odr-checker fix for conversion operators
This fixes an issue with the ODR checker not using the as-written type of conversion operators. The odr-checker in general should not have to deal with canonical types, as its purpose is to compare same definitions across TUs, and these need to be same as written, with few exceptions. Using canonical types is specially problematic when expressions are involved, as the types which refer to them generally pick an arbitrary representative expression, and this can lead to false mismatches. This patch makes sure that when hashing the names of declarations, the type source info contained in the DeclarationNameInfo is used instead of the one contained in the DeclarationName, which otherwise is always canonical. Fixes #144796
1 parent 526701f commit c5f95e9

File tree

4 files changed

+53
-14
lines changed

4 files changed

+53
-14
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ Improvements to Clang's diagnostics
656656
false positives in exception-heavy code, though only simple patterns
657657
are currently recognized.
658658

659-
659+
660660
Improvements to Clang's time-trace
661661
----------------------------------
662662

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

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

897898
Miscellaneous Bug Fixes

clang/include/clang/AST/ODRHash.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,13 @@ class ODRHash {
9696
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS);
9797
void AddDependentTemplateName(const DependentTemplateStorage &Name);
9898
void AddTemplateName(TemplateName Name);
99-
void AddDeclarationName(DeclarationName Name, bool TreatAsDecl = false);
99+
void AddDeclarationNameInfo(DeclarationNameInfo NameInfo,
100+
bool TreatAsDecl = false);
101+
void AddDeclarationName(DeclarationName Name, bool TreatAsDecl = false) {
102+
AddDeclarationNameInfo(DeclarationNameInfo(Name, SourceLocation()),
103+
TreatAsDecl);
104+
}
105+
100106
void AddTemplateArgument(TemplateArgument TA);
101107
void AddTemplateParameterList(const TemplateParameterList *TPL);
102108

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

110116
private:
111-
void AddDeclarationNameImpl(DeclarationName Name);
117+
void AddDeclarationNameInfoImpl(DeclarationNameInfo NameInfo);
112118
};
113119

114120
} // end namespace clang

clang/lib/AST/ODRHash.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,21 @@ void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {
3030
ID.AddString(II->getName());
3131
}
3232

33-
void ODRHash::AddDeclarationName(DeclarationName Name, bool TreatAsDecl) {
33+
void ODRHash::AddDeclarationNameInfo(DeclarationNameInfo NameInfo,
34+
bool TreatAsDecl) {
3435
if (TreatAsDecl)
3536
// Matches the NamedDecl check in AddDecl
3637
AddBoolean(true);
3738

38-
AddDeclarationNameImpl(Name);
39+
AddDeclarationNameInfoImpl(NameInfo);
3940

4041
if (TreatAsDecl)
4142
// Matches the ClassTemplateSpecializationDecl check in AddDecl
4243
AddBoolean(false);
4344
}
4445

45-
void ODRHash::AddDeclarationNameImpl(DeclarationName Name) {
46+
void ODRHash::AddDeclarationNameInfoImpl(DeclarationNameInfo NameInfo) {
47+
DeclarationName Name = NameInfo.getName();
4648
// Index all DeclarationName and use index numbers to refer to them.
4749
auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size()));
4850
ID.AddInteger(Result.first->second);
@@ -85,17 +87,18 @@ void ODRHash::AddDeclarationNameImpl(DeclarationName Name) {
8587
}
8688
case DeclarationName::CXXConstructorName:
8789
case DeclarationName::CXXDestructorName:
88-
AddQualType(Name.getCXXNameType());
90+
case DeclarationName::CXXConversionFunctionName:
91+
if (auto *TSI = NameInfo.getNamedTypeInfo())
92+
AddQualType(TSI->getType());
93+
else
94+
AddQualType(Name.getCXXNameType());
8995
break;
9096
case DeclarationName::CXXOperatorName:
9197
ID.AddInteger(Name.getCXXOverloadedOperator());
9298
break;
9399
case DeclarationName::CXXLiteralOperatorName:
94100
AddIdentifierInfo(Name.getCXXLiteralIdentifier());
95101
break;
96-
case DeclarationName::CXXConversionFunctionName:
97-
AddQualType(Name.getCXXNameType());
98-
break;
99102
case DeclarationName::CXXUsingDirective:
100103
break;
101104
case DeclarationName::CXXDeductionGuideName: {
@@ -314,7 +317,10 @@ class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
314317
}
315318

316319
void VisitNamedDecl(const NamedDecl *D) {
317-
Hash.AddDeclarationName(D->getDeclName());
320+
if (const auto *FD = dyn_cast<FunctionDecl>(D))
321+
Hash.AddDeclarationNameInfo(FD->getNameInfo());
322+
else
323+
Hash.AddDeclarationName(D->getDeclName());
318324
Inherited::VisitNamedDecl(D);
319325
}
320326

@@ -828,7 +834,10 @@ void ODRHash::AddDecl(const Decl *D) {
828834
return;
829835
}
830836

831-
AddDeclarationName(ND->getDeclName());
837+
if (auto *FD = dyn_cast<FunctionDecl>(D))
838+
AddDeclarationNameInfo(FD->getNameInfo());
839+
else
840+
AddDeclarationName(ND->getDeclName());
832841

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

10191028
void VisitDecltypeType(const DecltypeType *T) {
1020-
AddStmt(T->getUnderlyingExpr());
1029+
Hash.AddStmt(T->getUnderlyingExpr());
10211030
VisitType(T);
10221031
}
10231032

clang/test/Modules/odr_hash.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5164,6 +5164,29 @@ namespace A {
51645164
A::X x;
51655165
#endif
51665166

5167+
namespace TemplateDecltypeOperator {
5168+
5169+
#if defined(FIRST) || defined(SECOND)
5170+
template <class T6>
5171+
T6 func();
5172+
#endif
5173+
5174+
#if defined(SECOND)
5175+
template <class UnrelatedT>
5176+
using UnrelatedAlias = decltype(func<UnrelatedT>())();
5177+
#endif
5178+
5179+
#if defined(FIRST) || defined(SECOND)
5180+
class A {
5181+
template <class T6>
5182+
operator decltype(func<T6>()) () {}
5183+
};
5184+
#else
5185+
A a;
5186+
#endif
5187+
5188+
}
5189+
51675190
// Keep macros contained to one file.
51685191
#ifdef FIRST
51695192
#undef FIRST

0 commit comments

Comments
 (0)