r360563 - PR41845: Detect and reject mismatched inner/outer pack expansion sizes
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon May 13 01:31:14 PDT 2019
Author: rsmith
Date: Mon May 13 01:31:14 2019
New Revision: 360563
URL: http://llvm.org/viewvc/llvm-project?rev=360563&view=rev
Log:
PR41845: Detect and reject mismatched inner/outer pack expansion sizes
in fold expressions rather than crashing.
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
cfe/trunk/test/SemaTemplate/cxx1z-fold-expressions.cpp
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=360563&r1=360562&r2=360563&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Mon May 13 01:31:14 2019
@@ -4436,18 +4436,21 @@ class CXXFoldExpr : public Expr {
SourceLocation LParenLoc;
SourceLocation EllipsisLoc;
SourceLocation RParenLoc;
+ // When 0, the number of expansions is not known. Otherwise, this is one more
+ // than the number of expansions.
+ unsigned NumExpansions;
Stmt *SubExprs[2];
BinaryOperatorKind Opcode;
public:
CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS,
BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS,
- SourceLocation RParenLoc)
+ SourceLocation RParenLoc, Optional<unsigned> NumExpansions)
: Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary,
/*Dependent*/ true, true, true,
/*ContainsUnexpandedParameterPack*/ false),
LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
- Opcode(Opcode) {
+ NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
SubExprs[0] = LHS;
SubExprs[1] = RHS;
}
@@ -4474,6 +4477,12 @@ public:
SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
BinaryOperatorKind getOperator() const { return Opcode; }
+ Optional<unsigned> getNumExpansions() const {
+ if (NumExpansions)
+ return NumExpansions - 1;
+ return None;
+ }
+
SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=360563&r1=360562&r2=360563&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon May 13 01:31:14 2019
@@ -5204,7 +5204,8 @@ public:
ExprResult BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
BinaryOperatorKind Operator,
SourceLocation EllipsisLoc, Expr *RHS,
- SourceLocation RParenLoc);
+ SourceLocation RParenLoc,
+ Optional<unsigned> NumExpansions);
ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
BinaryOperatorKind Operator);
Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=360563&r1=360562&r2=360563&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Mon May 13 01:31:14 2019
@@ -1176,15 +1176,18 @@ ExprResult Sema::ActOnCXXFoldExpr(Source
}
BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator);
- return BuildCXXFoldExpr(LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc);
+ return BuildCXXFoldExpr(LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc,
+ None);
}
ExprResult Sema::BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
BinaryOperatorKind Operator,
SourceLocation EllipsisLoc, Expr *RHS,
- SourceLocation RParenLoc) {
+ SourceLocation RParenLoc,
+ Optional<unsigned> NumExpansions) {
return new (Context) CXXFoldExpr(Context.DependentTy, LParenLoc, LHS,
- Operator, EllipsisLoc, RHS, RParenLoc);
+ Operator, EllipsisLoc, RHS, RParenLoc,
+ NumExpansions);
}
ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=360563&r1=360562&r2=360563&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon May 13 01:31:14 2019
@@ -3254,9 +3254,10 @@ public:
ExprResult RebuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
BinaryOperatorKind Operator,
SourceLocation EllipsisLoc, Expr *RHS,
- SourceLocation RParenLoc) {
+ SourceLocation RParenLoc,
+ Optional<unsigned> NumExpansions) {
return getSema().BuildCXXFoldExpr(LParenLoc, LHS, Operator, EllipsisLoc,
- RHS, RParenLoc);
+ RHS, RParenLoc, NumExpansions);
}
/// Build an empty C++1z fold-expression with the given operator.
@@ -11823,7 +11824,8 @@ TreeTransform<Derived>::TransformCXXFold
// be expanded.
bool Expand = true;
bool RetainExpansion = false;
- Optional<unsigned> NumExpansions;
+ Optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
+ NumExpansions = OrigNumExpansions;
if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
Pattern->getSourceRange(),
Unexpanded,
@@ -11852,7 +11854,7 @@ TreeTransform<Derived>::TransformCXXFold
return getDerived().RebuildCXXFoldExpr(
E->getBeginLoc(), LHS.get(), E->getOperator(), E->getEllipsisLoc(),
- RHS.get(), E->getEndLoc());
+ RHS.get(), E->getEndLoc(), NumExpansions);
}
// The transform has determined that we should perform an elementwise
@@ -11873,7 +11875,7 @@ TreeTransform<Derived>::TransformCXXFold
Result = getDerived().RebuildCXXFoldExpr(
E->getBeginLoc(), Out.get(), E->getOperator(), E->getEllipsisLoc(),
- Result.get(), E->getEndLoc());
+ Result.get(), E->getEndLoc(), OrigNumExpansions);
if (Result.isInvalid())
return true;
}
@@ -11890,7 +11892,8 @@ TreeTransform<Derived>::TransformCXXFold
Result = getDerived().RebuildCXXFoldExpr(
E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
E->getOperator(), E->getEllipsisLoc(),
- LeftFold ? Out.get() : Result.get(), E->getEndLoc());
+ LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
+ OrigNumExpansions);
} else if (Result.isUsable()) {
// We've got down to a single element; build a binary operator.
Result = getDerived().RebuildBinaryOperator(
@@ -11915,7 +11918,7 @@ TreeTransform<Derived>::TransformCXXFold
Result = getDerived().RebuildCXXFoldExpr(
E->getBeginLoc(), Result.get(), E->getOperator(), E->getEllipsisLoc(),
- Out.get(), E->getEndLoc());
+ Out.get(), E->getEndLoc(), OrigNumExpansions);
if (Result.isInvalid())
return true;
}
Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=360563&r1=360562&r2=360563&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon May 13 01:31:14 2019
@@ -1810,6 +1810,7 @@ void ASTStmtReader::VisitCXXFoldExpr(CXX
E->LParenLoc = ReadSourceLocation();
E->EllipsisLoc = ReadSourceLocation();
E->RParenLoc = ReadSourceLocation();
+ E->NumExpansions = Record.readInt();
E->SubExprs[0] = Record.readSubExpr();
E->SubExprs[1] = Record.readSubExpr();
E->Opcode = (BinaryOperatorKind)Record.readInt();
Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=360563&r1=360562&r2=360563&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon May 13 01:31:14 2019
@@ -1780,6 +1780,7 @@ void ASTStmtWriter::VisitCXXFoldExpr(CXX
Record.AddSourceLocation(E->LParenLoc);
Record.AddSourceLocation(E->EllipsisLoc);
Record.AddSourceLocation(E->RParenLoc);
+ Record.push_back(E->NumExpansions);
Record.AddStmt(E->SubExprs[0]);
Record.AddStmt(E->SubExprs[1]);
Record.push_back(E->Opcode);
Modified: cfe/trunk/test/SemaTemplate/cxx1z-fold-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/cxx1z-fold-expressions.cpp?rev=360563&r1=360562&r2=360563&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/cxx1z-fold-expressions.cpp (original)
+++ cfe/trunk/test/SemaTemplate/cxx1z-fold-expressions.cpp Mon May 13 01:31:14 2019
@@ -92,3 +92,13 @@ template<typename ...T> constexpr auto s
template<typename ...T> constexpr auto binary_conditional1(T ...t) { return (t ?: ...); } // expected-error {{expected expression}}
template<typename ...T> constexpr auto binary_conditional2(T ...t) { return (... ?: t); } // expected-error {{expected expression}}
template<typename ...T> constexpr auto binary_conditional3(T ...t) { return (t ?: ... ?: 0); } // expected-error {{expected expression}}
+
+namespace PR41845 {
+ template <int I> struct Constant {};
+
+ template <int... Is> struct Sum {
+ template <int... Js> using type = Constant<((Is + Js) + ... + 0)>; // expected-error {{pack expansion contains parameter pack 'Js' that has a different length (1 vs. 2) from outer parameter packs}}
+ };
+
+ Sum<1>::type<1, 2> x; // expected-note {{instantiation of}}
+}
More information about the cfe-commits
mailing list