From 1df657da6cbc9b64228c3ef81d86917a85957237 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 17 Oct 2014 20:56:14 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220088 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/TemplateBase.cpp | 6 ++- lib/AST/Type.cpp | 37 ++----------------- test/SemaTemplate/dependent-type-identity.cpp | 23 +++++++++++- 3 files changed, 30 insertions(+), 36 deletions(-) diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index 929fdfc7ce..f07b18e7c1 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -90,7 +90,8 @@ bool TemplateArgument::isDependent() const { llvm_unreachable("Should not have a NULL template argument"); case Type: - return getAsType()->isDependentType(); + return getAsType()->isDependentType() || + isa(getAsType()); case Template: return getAsTemplate().isDependent(); @@ -111,7 +112,8 @@ bool TemplateArgument::isDependent() const { return false; case Expression: - return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent()); + return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() || + isa(getAsExpr())); case Pack: for (const auto &P : pack_elements()) diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 3c5e80e9ba..4bf5927f6b 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1980,32 +1980,14 @@ anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N, 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, 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(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 T, // U is always non-dependent, irrespective of the type T. // However, U 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]); } diff --git a/test/SemaTemplate/dependent-type-identity.cpp b/test/SemaTemplate/dependent-type-identity.cpp index a796834ce0..5b9da5d892 100644 --- a/test/SemaTemplate/dependent-type-identity.cpp +++ b/test/SemaTemplate/dependent-type-identity.cpp @@ -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; template struct A; } + +namespace PR21289 { + template using X = int; + template using Y = int; + template struct S {}; + template void f() { + // This is a dependent type. It is *not* S, even though it canonically + // contains no template parameters. + using Type = S...>; + Type s; + using Type = S; + } + void g() { f(); } + + template void h(S) {} + // 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 void h(S...>) {} // expected-note {{previous}} + template void h(S...>) {} // expected-error {{redefinition}} +} -- 2.40.0