-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang] fix broken canonicalization of DeducedTemplateSpecializationType
This reverts the functional elements of commit 3e78fa8 and redoes it, by fixing the true root cause of #61317. A TemplateName can be non-canonical; profiling it based on the canonical name would result in inconsistent preservation of as-written information in the AST. The true problem in #61317 is that we would not consider the methods with requirements expression which contain DTSTs as the same in relation to merging of declarations when importing modules. The expressions would never match because they contained DTSTs pointing to different redeclarations of the same class template, but since canonicalization for them was broken, their canonical types would not match either. --- No changelog entry because #61317 was already claimed as fixed in previous release.
- Loading branch information
Showing
7 changed files
with
107 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
//===- unittests/AST/ProfilingTest.cpp --- Tests for Profiling ------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "clang/AST/ASTContext.h" | ||
#include "clang/ASTMatchers/ASTMatchFinder.h" | ||
#include "clang/ASTMatchers/ASTMatchers.h" | ||
#include "clang/Tooling/Tooling.h" | ||
#include "gtest/gtest.h" | ||
#include <utility> | ||
|
||
namespace clang { | ||
namespace { | ||
using namespace ast_matchers; | ||
|
||
static auto getClassTemplateRedecls() { | ||
std::string Code = R"cpp( | ||
template <class> struct A; | ||
template <class> struct A; | ||
template <class> struct A; | ||
)cpp"; | ||
auto AST = tooling::buildASTFromCode(Code); | ||
ASTContext &Ctx = AST->getASTContext(); | ||
|
||
auto MatchResults = match(classTemplateDecl().bind("id"), Ctx); | ||
SmallVector<ClassTemplateDecl *, 3> Res; | ||
for (BoundNodes &N : MatchResults) { | ||
if (auto *CTD = const_cast<ClassTemplateDecl *>( | ||
N.getNodeAs<ClassTemplateDecl>("id"))) | ||
Res.push_back(CTD); | ||
} | ||
assert(Res.size() == 3); | ||
for (auto &&I : Res) | ||
assert(I->getCanonicalDecl() == Res[0]); | ||
return std::make_tuple(std::move(AST), Res[1], Res[2]); | ||
} | ||
|
||
template <class T> static void testTypeNode(const T *T1, const T *T2) { | ||
{ | ||
llvm::FoldingSetNodeID ID1, ID2; | ||
T1->Profile(ID1); | ||
T2->Profile(ID2); | ||
ASSERT_NE(ID1, ID2); | ||
} | ||
auto *CT1 = cast<T>(T1->getCanonicalTypeInternal()); | ||
auto *CT2 = cast<T>(T2->getCanonicalTypeInternal()); | ||
{ | ||
llvm::FoldingSetNodeID ID1, ID2; | ||
CT1->Profile(ID1); | ||
CT2->Profile(ID2); | ||
ASSERT_EQ(ID1, ID2); | ||
} | ||
} | ||
|
||
TEST(Profiling, DeducedTemplateSpecializationType_Name) { | ||
auto [AST, CTD1, CTD2] = getClassTemplateRedecls(); | ||
ASTContext &Ctx = AST->getASTContext(); | ||
|
||
auto *T1 = cast<DeducedTemplateSpecializationType>( | ||
Ctx.getDeducedTemplateSpecializationType(TemplateName(CTD1), QualType(), | ||
false)); | ||
auto *T2 = cast<DeducedTemplateSpecializationType>( | ||
Ctx.getDeducedTemplateSpecializationType(TemplateName(CTD2), QualType(), | ||
false)); | ||
testTypeNode(T1, T2); | ||
} | ||
|
||
} // namespace | ||
} // namespace clang |