-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Revert "[Clang][Sema] Handle invalid variable template specialization whose type depends on itself (#134522)" #139539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… whose type depends on itself (llvm#134522)" This reverts commit 91f1830.
@llvm/pr-subscribers-clang Author: Yanzuo Liu (zwuis) Changes#134522 triggers compilation error with libstdc++. See #139067 or <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120190>. This reverts commit 91f1830. Full diff: https://github.com/llvm/llvm-project/pull/139539.diff 10 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e362ec595a3bb..d0645f3cbc6a5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -684,8 +684,6 @@ Bug Fixes to C++ Support
- Fixed an assertion when trying to constant-fold various builtins when the argument
referred to a reference to an incomplete type. (#GH129397)
- Fixed a crash when a cast involved a parenthesized aggregate initialization in dependent context. (#GH72880)
-- No longer crashes when instantiating invalid variable template specialization
- whose type depends on itself. (#GH51347), (#GH55872)
- Improved parser recovery of invalid requirement expressions. In turn, this
fixes crashes from follow-on processing of the invalid requirement. (#GH138820)
- Fixed the handling of pack indexing types in the constraints of a member function redeclaration. (#GH138255)
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 1fdc488a76507..555afc315b704 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -2971,11 +2971,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
TemplateTemplateParmDecl *insertCanonicalTemplateTemplateParmDeclInternal(
TemplateTemplateParmDecl *CanonTTP) const;
- /// Determine whether the given template arguments \p Arg1 and \p Arg2 are
- /// equivalent.
- bool isSameTemplateArgument(const TemplateArgument &Arg1,
- const TemplateArgument &Arg2) const;
-
/// Type Query functions. If the type is an instance of the specified class,
/// return the Type pointer for the underlying maximally pretty type. This
/// is a member of ASTContext because this may need to do some amount of
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ca47cf62324f3..4751acfbb0456 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2531,14 +2531,9 @@ def note_implicit_deduction_guide : Note<"implicit deduction guide declared as '
def warn_cxx98_compat_auto_type_specifier : Warning<
"'auto' type specifier is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
-def err_auto_variable_cannot_appear_in_own_initializer
- : Error<
- "%enum_select<ParsingInitFor>{%Var{variable}|"
- "%VarTemplate{variable template}|"
- "%VarTemplatePartialSpec{variable template partial specialization}|"
- "%VarTemplateExplicitSpec{variable template explicit "
- "specialization}}0 %1 "
- "declared with deduced type %2 cannot appear in its own initializer">;
+def err_auto_variable_cannot_appear_in_own_initializer : Error<
+ "variable %0 declared with deduced type %1 "
+ "cannot appear in its own initializer">;
def err_binding_cannot_appear_in_own_initializer : Error<
"binding %0 cannot appear in the initializer of its own "
"decomposition declaration">;
@@ -5312,9 +5307,6 @@ def err_template_member_noparams : Error<
"extraneous 'template<>' in declaration of member %0">;
def err_template_tag_noparams : Error<
"extraneous 'template<>' in declaration of %0 %1">;
-def err_var_template_spec_type_depends_on_self : Error<
- "the type of variable template specialization %0 declared with deduced type "
- "%1 depends on itself">;
def warn_unqualified_call_to_std_cast_function : Warning<
"unqualified call to '%0'">, InGroup<DiagGroup<"unqualified-std-cast-call">>;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c58cd2c93fb60..6b8685ae99256 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -7666,55 +7666,6 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
llvm_unreachable("Unhandled template argument kind");
}
-bool ASTContext::isSameTemplateArgument(const TemplateArgument &Arg1,
- const TemplateArgument &Arg2) const {
- if (Arg1.getKind() != Arg2.getKind())
- return false;
-
- switch (Arg1.getKind()) {
- case TemplateArgument::Null:
- llvm_unreachable("Comparing NULL template argument");
-
- case TemplateArgument::Type:
- return hasSameType(Arg1.getAsType(), Arg2.getAsType());
-
- case TemplateArgument::Declaration:
- return Arg1.getAsDecl()->getUnderlyingDecl()->getCanonicalDecl() ==
- Arg2.getAsDecl()->getUnderlyingDecl()->getCanonicalDecl();
-
- case TemplateArgument::NullPtr:
- return hasSameType(Arg1.getNullPtrType(), Arg2.getNullPtrType());
-
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- return getCanonicalTemplateName(Arg1.getAsTemplateOrTemplatePattern()) ==
- getCanonicalTemplateName(Arg2.getAsTemplateOrTemplatePattern());
-
- case TemplateArgument::Integral:
- return llvm::APSInt::isSameValue(Arg1.getAsIntegral(),
- Arg2.getAsIntegral());
-
- case TemplateArgument::StructuralValue:
- return Arg1.structurallyEquals(Arg2);
-
- case TemplateArgument::Expression: {
- llvm::FoldingSetNodeID ID1, ID2;
- Arg1.getAsExpr()->Profile(ID1, *this, /*Canonical=*/true);
- Arg2.getAsExpr()->Profile(ID2, *this, /*Canonical=*/true);
- return ID1 == ID2;
- }
-
- case TemplateArgument::Pack:
- return llvm::equal(
- Arg1.getPackAsArray(), Arg2.getPackAsArray(),
- [&](const TemplateArgument &Arg1, const TemplateArgument &Arg2) {
- return isSameTemplateArgument(Arg1, Arg2);
- });
- }
-
- llvm_unreachable("Unhandled template argument kind");
-}
-
NestedNameSpecifier *
ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
if (!NNS)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2c81f7c583eb6..4af9b6f0a1f56 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -251,8 +251,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
<< D->getDeclName();
} else {
Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer)
- << diag::ParsingInitFor::Var << D->getDeclName()
- << cast<VarDecl>(D)->getType();
+ << D->getDeclName() << cast<VarDecl>(D)->getType();
}
return true;
}
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 7940340064eda..8ccfdb80e1ce5 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4373,43 +4373,8 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
// Produce a placeholder value if the specialization is dependent.
if (Template->getDeclContext()->isDependentContext() ||
TemplateSpecializationType::anyDependentTemplateArguments(
- TemplateArgs, CTAI.CanonicalConverted)) {
- if (ParsingInitForAutoVars.empty())
- return DeclResult();
-
- auto IsSameTemplateArg = [&](const TemplateArgument &Arg1,
- const TemplateArgument &Arg2) {
- return Context.isSameTemplateArgument(Arg1, Arg2);
- };
-
- if (VarDecl *Var = Template->getTemplatedDecl();
- ParsingInitForAutoVars.count(Var) &&
- llvm::equal(
- CTAI.CanonicalConverted,
- Template->getTemplateParameters()->getInjectedTemplateArgs(Context),
- IsSameTemplateArg)) {
- Diag(TemplateNameLoc,
- diag::err_auto_variable_cannot_appear_in_own_initializer)
- << diag::ParsingInitFor::VarTemplate << Var << Var->getType();
- return true;
- }
-
- SmallVector<VarTemplatePartialSpecializationDecl *, 4> PartialSpecs;
- Template->getPartialSpecializations(PartialSpecs);
- for (VarTemplatePartialSpecializationDecl *Partial : PartialSpecs)
- if (ParsingInitForAutoVars.count(Partial) &&
- llvm::equal(CTAI.CanonicalConverted,
- Partial->getTemplateArgs().asArray(),
- IsSameTemplateArg)) {
- Diag(TemplateNameLoc,
- diag::err_auto_variable_cannot_appear_in_own_initializer)
- << diag::ParsingInitFor::VarTemplatePartialSpec << Partial
- << Partial->getType();
- return true;
- }
-
+ TemplateArgs, CTAI.CanonicalConverted))
return DeclResult();
- }
// Find the variable template specialization declaration that
// corresponds to these arguments.
@@ -4417,20 +4382,6 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
if (VarTemplateSpecializationDecl *Spec =
Template->findSpecialization(CTAI.CanonicalConverted, InsertPos)) {
checkSpecializationReachability(TemplateNameLoc, Spec);
- if (Spec->getType()->isUndeducedType()) {
- if (ParsingInitForAutoVars.count(Spec))
- Diag(TemplateNameLoc,
- diag::err_auto_variable_cannot_appear_in_own_initializer)
- << diag::ParsingInitFor::VarTemplateExplicitSpec << Spec
- << Spec->getType();
- else
- // We are substituting the initializer of this variable template
- // specialization.
- Diag(TemplateNameLoc, diag::err_var_template_spec_type_depends_on_self)
- << Spec << Spec->getType();
-
- return true;
- }
// If we already have a variable template specialization, return it.
return Spec;
}
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 5dc06ebc2a235..b3505bad281f2 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -114,6 +114,27 @@ namespace clang {
using namespace clang;
using namespace sema;
+/// Compare two APSInts, extending and switching the sign as
+/// necessary to compare their values regardless of underlying type.
+static bool hasSameExtendedValue(llvm::APSInt X, llvm::APSInt Y) {
+ if (Y.getBitWidth() > X.getBitWidth())
+ X = X.extend(Y.getBitWidth());
+ else if (Y.getBitWidth() < X.getBitWidth())
+ Y = Y.extend(X.getBitWidth());
+
+ // If there is a signedness mismatch, correct it.
+ if (X.isSigned() != Y.isSigned()) {
+ // If the signed value is negative, then the values cannot be the same.
+ if ((Y.isSigned() && Y.isNegative()) || (X.isSigned() && X.isNegative()))
+ return false;
+
+ Y.setIsSigned(true);
+ X.setIsSigned(true);
+ }
+
+ return X == Y;
+}
+
/// The kind of PartialOrdering we're performing template argument deduction
/// for (C++11 [temp.deduct.partial]).
enum class PartialOrderingKind { None, NonCall, Call };
@@ -252,7 +273,7 @@ checkDeducedTemplateArguments(ASTContext &Context,
if (Y.getKind() == TemplateArgument::Expression ||
Y.getKind() == TemplateArgument::Declaration ||
(Y.getKind() == TemplateArgument::Integral &&
- llvm::APSInt::isSameValue(X.getAsIntegral(), Y.getAsIntegral())))
+ hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral())))
return X.wasDeducedFromArrayBound() ? Y : X;
// All other combinations are incompatible.
@@ -2553,7 +2574,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
case TemplateArgument::Integral:
if (A.getKind() == TemplateArgument::Integral) {
- if (llvm::APSInt::isSameValue(P.getAsIntegral(), A.getAsIntegral()))
+ if (hasSameExtendedValue(P.getAsIntegral(), A.getAsIntegral()))
return TemplateDeductionResult::Success;
}
Info.FirstArg = P;
@@ -2807,6 +2828,62 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
/*HasDeducedAnyParam=*/nullptr);
}
+/// Determine whether two template arguments are the same.
+static bool isSameTemplateArg(ASTContext &Context, const TemplateArgument &X,
+ const TemplateArgument &Y) {
+ if (X.getKind() != Y.getKind())
+ return false;
+
+ switch (X.getKind()) {
+ case TemplateArgument::Null:
+ llvm_unreachable("Comparing NULL template argument");
+
+ case TemplateArgument::Type:
+ return Context.getCanonicalType(X.getAsType()) ==
+ Context.getCanonicalType(Y.getAsType());
+
+ case TemplateArgument::Declaration:
+ return isSameDeclaration(X.getAsDecl(), Y.getAsDecl());
+
+ case TemplateArgument::NullPtr:
+ return Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType());
+
+ case TemplateArgument::Template:
+ case TemplateArgument::TemplateExpansion:
+ return Context.getCanonicalTemplateName(
+ X.getAsTemplateOrTemplatePattern()).getAsVoidPointer() ==
+ Context.getCanonicalTemplateName(
+ Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer();
+
+ case TemplateArgument::Integral:
+ return hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral());
+
+ case TemplateArgument::StructuralValue:
+ return X.structurallyEquals(Y);
+
+ case TemplateArgument::Expression: {
+ llvm::FoldingSetNodeID XID, YID;
+ X.getAsExpr()->Profile(XID, Context, true);
+ Y.getAsExpr()->Profile(YID, Context, true);
+ return XID == YID;
+ }
+
+ case TemplateArgument::Pack: {
+ unsigned PackIterationSize = X.pack_size();
+ if (X.pack_size() != Y.pack_size())
+ return false;
+ ArrayRef<TemplateArgument> XP = X.pack_elements();
+ ArrayRef<TemplateArgument> YP = Y.pack_elements();
+ for (unsigned i = 0; i < PackIterationSize; ++i)
+ if (!isSameTemplateArg(Context, XP[i], YP[i]))
+ return false;
+ return true;
+ }
+ }
+
+ llvm_unreachable("Invalid TemplateArgument Kind!");
+}
+
TemplateArgumentLoc
Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
QualType NTTPType, SourceLocation Loc,
@@ -3272,7 +3349,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
break;
TemplateArgument PP = P.isPackExpansion() ? P.getPackExpansionPattern() : P,
PA = A.isPackExpansion() ? A.getPackExpansionPattern() : A;
- if (!S.Context.isSameTemplateArgument(PP, PA)) {
+ if (!isSameTemplateArg(S.Context, PP, PA)) {
if (!P.isPackExpansion() && !A.isPackExpansion()) {
Info.Param = makeTemplateParameter(TPL->getParam(
(AsStack.empty() ? As.end() : AsStack.back().begin()) -
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index 57a48fac56cd6..eafadb07b29e1 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -412,26 +412,6 @@ namespace dependent_static_var_template {
}
int cf() { return F<int>(); }
-
-#ifdef CPP1Y
- namespace GH55872 {
- struct s {
- template<typename T>
- static CONST auto f = [] { return T::template g<s>; };
- // expected-note@-1 {{in instantiation of static data member 'dependent_static_var_template::GH55872::t::g' requested here}}
- // expected-note@-2 {{while substituting into a lambda expression here}}
- };
-
- struct t {
- template<typename T>
- static CONST auto g = [] { return T::template f<t>; };
- // expected-error@-1 {{the type of variable template specialization 'f<dependent_static_var_template::GH55872::t>' declared with deduced type 'const auto' depends on itself}}
- // expected-note@-2 {{while substituting into a lambda expression here}}
- };
-
- void test() { s::f<t>()(); } // expected-note {{in instantiation of static data member 'dependent_static_var_template::GH55872::s::f' requested here}}
- }
-#endif
}
#ifndef PRECXX11
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
index 1fe0ce9aabf29..6fc2032ee7fb4 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -492,21 +492,4 @@ static_assert(C<int, 0,1,2,3,4>::VALUEARRAY[3] == 3, "");
static_assert(C<int, 0,1,2,3,4>::VALUEARRAY[0] == 0, "");
}
-
-namespace appear_in_its_own_init {
-template <class T>
-auto GH51347 = GH51347<T>; // expected-error {{variable template 'GH51347' declared with deduced type 'auto' cannot appear in its own initializer}}
-
-template <class T, class... Ts>
-auto a = [] {
- using U = T;
- a<U, Ts...>; // expected-error {{variable template 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
-};
-
-template <int...> int b;
-template <int I>
-auto b<I, I * 2, 5> = b<I, I * 2, 5l>; // expected-error {{variable template partial specialization 'b<I, I * 2, 5>' declared with deduced type 'auto' cannot appear in its own initializer}}
-template <> auto b<0, 0, 0> = b<0, 0, 0>; // expected-error {{variable template explicit specialization 'b<0, 0, 0>' declared with deduced type 'auto' cannot appear in its own initializer}}
-}
-
#endif
diff --git a/clang/test/SemaTemplate/instantiate-var-template.cpp b/clang/test/SemaTemplate/instantiate-var-template.cpp
index 50b7219af4bea..60d3bd3b59f53 100644
--- a/clang/test/SemaTemplate/instantiate-var-template.cpp
+++ b/clang/test/SemaTemplate/instantiate-var-template.cpp
@@ -47,14 +47,3 @@ namespace InvalidInsertPos {
template<> int v<int, 0>;
int k = v<int, 500>;
}
-
-namespace GH97881_comment {
- template <bool B>
- auto g = sizeof(g<!B>);
- // expected-error@-1 {{the type of variable template specialization 'g<false>'}}
- // expected-note@-2 {{in instantiation of variable template specialization 'GH97881_comment::g'}}
-
- void test() {
- (void)sizeof(g<false>); // expected-note {{in instantiation of variable template specialization 'GH97881_comment::g'}}
- }
-}
|
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- clang/include/clang/AST/ASTContext.h clang/lib/AST/ASTContext.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp clang/test/SemaTemplate/instantiate-var-template.cpp View the diff from clang-format here.diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 4af9b6f0a..cc8d5f1aa 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -251,7 +251,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
<< D->getDeclName();
} else {
Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer)
- << D->getDeclName() << cast<VarDecl>(D)->getType();
+ << D->getDeclName() << cast<VarDecl>(D)->getType();
}
return true;
}
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index b3505bad2..26b21fe51 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2835,50 +2835,50 @@ static bool isSameTemplateArg(ASTContext &Context, const TemplateArgument &X,
return false;
switch (X.getKind()) {
- case TemplateArgument::Null:
- llvm_unreachable("Comparing NULL template argument");
+ case TemplateArgument::Null:
+ llvm_unreachable("Comparing NULL template argument");
- case TemplateArgument::Type:
- return Context.getCanonicalType(X.getAsType()) ==
- Context.getCanonicalType(Y.getAsType());
+ case TemplateArgument::Type:
+ return Context.getCanonicalType(X.getAsType()) ==
+ Context.getCanonicalType(Y.getAsType());
- case TemplateArgument::Declaration:
- return isSameDeclaration(X.getAsDecl(), Y.getAsDecl());
+ case TemplateArgument::Declaration:
+ return isSameDeclaration(X.getAsDecl(), Y.getAsDecl());
- case TemplateArgument::NullPtr:
- return Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType());
+ case TemplateArgument::NullPtr:
+ return Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType());
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- return Context.getCanonicalTemplateName(
- X.getAsTemplateOrTemplatePattern()).getAsVoidPointer() ==
- Context.getCanonicalTemplateName(
- Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer();
-
- case TemplateArgument::Integral:
- return hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral());
-
- case TemplateArgument::StructuralValue:
- return X.structurallyEquals(Y);
-
- case TemplateArgument::Expression: {
- llvm::FoldingSetNodeID XID, YID;
- X.getAsExpr()->Profile(XID, Context, true);
- Y.getAsExpr()->Profile(YID, Context, true);
- return XID == YID;
- }
+ case TemplateArgument::Template:
+ case TemplateArgument::TemplateExpansion:
+ return Context.getCanonicalTemplateName(X.getAsTemplateOrTemplatePattern())
+ .getAsVoidPointer() ==
+ Context.getCanonicalTemplateName(Y.getAsTemplateOrTemplatePattern())
+ .getAsVoidPointer();
- case TemplateArgument::Pack: {
- unsigned PackIterationSize = X.pack_size();
- if (X.pack_size() != Y.pack_size())
+ case TemplateArgument::Integral:
+ return hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral());
+
+ case TemplateArgument::StructuralValue:
+ return X.structurallyEquals(Y);
+
+ case TemplateArgument::Expression: {
+ llvm::FoldingSetNodeID XID, YID;
+ X.getAsExpr()->Profile(XID, Context, true);
+ Y.getAsExpr()->Profile(YID, Context, true);
+ return XID == YID;
+ }
+
+ case TemplateArgument::Pack: {
+ unsigned PackIterationSize = X.pack_size();
+ if (X.pack_size() != Y.pack_size())
+ return false;
+ ArrayRef<TemplateArgument> XP = X.pack_elements();
+ ArrayRef<TemplateArgument> YP = Y.pack_elements();
+ for (unsigned i = 0; i < PackIterationSize; ++i)
+ if (!isSameTemplateArg(Context, XP[i], YP[i]))
return false;
- ArrayRef<TemplateArgument> XP = X.pack_elements();
- ArrayRef<TemplateArgument> YP = Y.pack_elements();
- for (unsigned i = 0; i < PackIterationSize; ++i)
- if (!isSameTemplateArg(Context, XP[i], YP[i]))
- return false;
- return true;
- }
+ return true;
+ }
}
llvm_unreachable("Invalid TemplateArgument Kind!");
|
This would be quite disappointing to me. As much as I strongly dislike that we don't build a standard library, this patch fixed a handful of bugs in a really nice manner. I'd vastly prefer if someone could prepare a 'compatibility' hack here. Even something as absolutely crazy as just skipping the args of |
#134522 triggers compilation error with libstdc++. See #139067 or https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120190.
This reverts commit 91f1830.