Skip to content

Commit

Permalink
PR47792: Include the type of a pointer or reference non-type template
Browse files Browse the repository at this point in the history
parameter in its notion of template argument identity.

We already did this for all the other kinds of non-type template
argument. We're still missing the type from the mangling, so we continue
to be able to see collisions at link time; that's an open ABI issue.
  • Loading branch information
zygoloid committed Oct 11, 2020
1 parent 9e72d3e commit 849c605
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
2 changes: 1 addition & 1 deletion clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5890,7 +5890,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {

case TemplateArgument::Declaration: {
auto *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());
return TemplateArgument(D, Arg.getParamTypeForDecl());
return TemplateArgument(D, getCanonicalType(Arg.getParamTypeForDecl()));
}

case TemplateArgument::NullPtr:
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/AST/TemplateBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
break;

case Declaration:
ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
ID.AddPointer(getAsDecl() ? getAsDecl()->getCanonicalDecl() : nullptr);
getParamTypeForDecl().Profile(ID);
break;

case Template:
Expand Down Expand Up @@ -294,7 +295,8 @@ bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
return TypeOrValue.V == Other.TypeOrValue.V;

case Declaration:
return getAsDecl() == Other.getAsDecl();
return getAsDecl() == Other.getAsDecl() &&
getParamTypeForDecl() == Other.getParamTypeForDecl();

case Integral:
return getIntegralType() == Other.getIntegralType() &&
Expand Down
20 changes: 20 additions & 0 deletions clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,23 @@ namespace PR46637 {
X<f> y;
int n = y.call(); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void *'}}
}

namespace PR47792 {
using I = int;

template<decltype(auto)> int a;
const int n = 0;
const I n2 = 0;
static_assert(&a<n> == &a<0>, "both should have type 'int'");
static_assert(&a<n2> == &a<0>, "both should have type 'int'");

// FIXME: We will need to mangle these cases differently too!
int m;
const int &r1 = m;
int &r2 = m;
static_assert(&a<r1> != &a<r2>, "should have different types");

const I &r3 = m;
static_assert(&a<r1> == &a<r3>, "should have different types");
static_assert(&a<r2> != &a<r3>, "should have different types");
}

0 comments on commit 849c605

Please sign in to comment.