Skip to content

Commit

Permalink
[C++20] [Modules] [Concepts] Recognize same concepts more precisely i…
Browse files Browse the repository at this point in the history
…n Serialization

The compiler would judge two concepts is same by their addresses.
However, when we use modules, the addresses wouldn't be the same all the
time since one is parsed in their TU and another is imported in another
TU.
This patch fixes this by using isSameEntity to judge the two concepts.

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D114769
  • Loading branch information
ChuanqiXu9 committed Dec 8, 2021
1 parent b1c369e commit e166755
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 3 deletions.
10 changes: 7 additions & 3 deletions clang/lib/Serialization/ASTReaderDecl.cpp
Expand Up @@ -2948,6 +2948,7 @@ uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint64_t LocalOffset) {
static bool isSameTemplateParameterList(const ASTContext &C,
const TemplateParameterList *X,
const TemplateParameterList *Y);
static bool isSameEntity(NamedDecl *X, NamedDecl *Y);

/// Determine whether two template parameters are similar enough
/// that they may be used in declarations of the same template.
Expand All @@ -2967,7 +2968,9 @@ static bool isSameTemplateParameter(const NamedDecl *X,
if (!TXTC != !TYTC)
return false;
if (TXTC && TYTC) {
if (TXTC->getNamedConcept() != TYTC->getNamedConcept())
auto *NCX = TXTC->getNamedConcept();
auto *NCY = TYTC->getNamedConcept();
if (!NCX || !NCY || !isSameEntity(NCX, NCY))
return false;
if (TXTC->hasExplicitTemplateArgs() != TYTC->hasExplicitTemplateArgs())
return false;
Expand Down Expand Up @@ -3111,11 +3114,12 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A,

/// Determine whether the two declarations refer to the same entity.
static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!");

if (X == Y)
return true;

if (X->getDeclName() != Y->getDeclName())
return false;

// Must be in the same context.
//
// Note that we can't use DeclContext::Equals here, because the DeclContexts
Expand Down
3 changes: 3 additions & 0 deletions clang/test/Modules/Inputs/concept/A.cppm
@@ -0,0 +1,3 @@
module;
#include "foo.h"
export module A;
13 changes: 13 additions & 0 deletions clang/test/Modules/Inputs/concept/foo.h
@@ -0,0 +1,13 @@
#ifndef FOO_H
#define FOO_H

template <class T>
concept Range = requires(T &t) { t.begin(); };

struct A {
public:
template <Range T>
using range_type = T;
};

#endif
10 changes: 10 additions & 0 deletions clang/test/Modules/concept.cppm
@@ -0,0 +1,10 @@
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: %clang -std=c++20 %S/Inputs/concept/A.cppm --precompile -o %t/A.pcm
// RUN: %clang -std=c++20 -fprebuilt-module-path=%t -I%S/Inputs/concept %s -c -Xclang -verify
// expected-no-diagnostics

module;
#include "foo.h"
export module B;
import A;

0 comments on commit e166755

Please sign in to comment.