r220088 - Fix the rest of PR21289: a pack expansion that we can't expand yet makes a
Richard Smith
richard-llvm at metafoo.co.uk
Fri Oct 17 13:56:14 PDT 2014
Author: rsmith
Date: Fri Oct 17 15:56:14 2014
New Revision: 220088
URL: http://llvm.org/viewvc/llvm-project?rev=220088&view=rev
Log:
Fix the rest of PR21289: a pack expansion that we can't expand yet makes a
template specialization type dependent, even if it has no dependent template
arguments. I've filed a corresponding bug against the C++ standard.
Modified:
cfe/trunk/lib/AST/TemplateBase.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp
Modified: cfe/trunk/lib/AST/TemplateBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=220088&r1=220087&r2=220088&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateBase.cpp (original)
+++ cfe/trunk/lib/AST/TemplateBase.cpp Fri Oct 17 15:56:14 2014
@@ -90,7 +90,8 @@ bool TemplateArgument::isDependent() con
llvm_unreachable("Should not have a NULL template argument");
case Type:
- return getAsType()->isDependentType();
+ return getAsType()->isDependentType() ||
+ isa<PackExpansionType>(getAsType());
case Template:
return getAsTemplate().isDependent();
@@ -111,7 +112,8 @@ bool TemplateArgument::isDependent() con
return false;
case Expression:
- return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
+ return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() ||
+ isa<PackExpansionExpr>(getAsExpr()));
case Pack:
for (const auto &P : pack_elements())
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=220088&r1=220087&r2=220088&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Fri Oct 17 15:56:14 2014
@@ -1980,32 +1980,14 @@ anyDependentTemplateArguments(const Temp
return false;
}
-#ifndef NDEBUG
-static bool
-anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N,
- bool &InstantiationDependent) {
- for (unsigned i = 0; i != N; ++i) {
- if (Args[i].isDependent()) {
- InstantiationDependent = true;
- return true;
- }
-
- if (Args[i].isInstantiationDependent())
- InstantiationDependent = true;
- }
- return false;
-}
-#endif
-
TemplateSpecializationType::
TemplateSpecializationType(TemplateName T,
const TemplateArgument *Args, unsigned NumArgs,
QualType Canon, QualType AliasedType)
: Type(TemplateSpecialization,
Canon.isNull()? QualType(this, 0) : Canon,
- Canon.isNull()? T.isDependent() : Canon->isDependentType(),
- Canon.isNull()? T.isDependent()
- : Canon->isInstantiationDependentType(),
+ Canon.isNull()? true : Canon->isDependentType(),
+ Canon.isNull()? true : Canon->isInstantiationDependentType(),
false,
T.containsUnexpandedParameterPack()),
Template(T), NumArgs(NumArgs), TypeAlias(!AliasedType.isNull()) {
@@ -2015,18 +1997,11 @@ TemplateSpecializationType(TemplateName
T.getKind() == TemplateName::SubstTemplateTemplateParm ||
T.getKind() == TemplateName::SubstTemplateTemplateParmPack) &&
"Unexpected template name for TemplateSpecializationType");
- bool InstantiationDependent;
- (void)InstantiationDependent;
- assert((!Canon.isNull() ||
- T.isDependent() ||
- ::anyDependentTemplateArguments(Args, NumArgs,
- InstantiationDependent)) &&
- "No canonical type for non-dependent class template specialization");
TemplateArgument *TemplateArgs
= reinterpret_cast<TemplateArgument *>(this + 1);
for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
- // Update dependent and variably-modified bits.
+ // Update instantiation-dependent and variably-modified bits.
// If the canonical type exists and is non-dependent, the template
// specialization type can be non-dependent even if one of the type
// arguments is. Given:
@@ -2034,17 +2009,13 @@ TemplateSpecializationType(TemplateName
// U<T> is always non-dependent, irrespective of the type T.
// However, U<Ts> contains an unexpanded parameter pack, even though
// its expansion (and thus its desugared type) doesn't.
- if (Canon.isNull() && Args[Arg].isDependent())
- setDependent();
- else if (Args[Arg].isInstantiationDependent())
+ if (Args[Arg].isInstantiationDependent())
setInstantiationDependent();
-
if (Args[Arg].getKind() == TemplateArgument::Type &&
Args[Arg].getAsType()->isVariablyModifiedType())
setVariablyModified();
if (Args[Arg].containsUnexpandedParameterPack())
setContainsUnexpandedParameterPack();
-
new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]);
}
Modified: cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp?rev=220088&r1=220087&r2=220088&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp Fri Oct 17 15:56:14 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// This test concerns the identity of dependent types within the
// canonical type system. This corresponds to C++ [temp.type], which
@@ -122,3 +122,24 @@ namespace PR18275 {
template struct A<int>;
template struct A<int[1]>;
}
+
+namespace PR21289 {
+ template<typename T> using X = int;
+ template<typename T, decltype(sizeof(0))> using Y = int;
+ template<typename ...Ts> struct S {};
+ template<typename ...Ts> void f() {
+ // This is a dependent type. It is *not* S<int>, even though it canonically
+ // contains no template parameters.
+ using Type = S<X<Ts>...>;
+ Type s;
+ using Type = S<int, int, int>;
+ }
+ void g() { f<void, void, void>(); }
+
+ template<typename ...Ts> void h(S<int>) {}
+ // Pending a core issue, it's not clear if these are redeclarations, but they
+ // are probably intended to be... even though substitution can succeed for one
+ // of them but fail for the other!
+ template<typename ...Ts> void h(S<X<Ts>...>) {} // expected-note {{previous}}
+ template<typename ...Ts> void h(S<Y<Ts, sizeof(Ts)>...>) {} // expected-error {{redefinition}}
+}
More information about the cfe-commits
mailing list