The attached patch
- fixes the introduction of null types for ParenListExpr's that end up
in the AST for explicit initializers by making the constructor of
ParenListExpr take a type (as suggested by dgregor on irc)
- gets rid of some code I assume is dead (tested by running the tests
and by running it over all of our internal C++ code without hitting
any of those asserts - and by my inability to come up with an example
that hits that code path (which admittedly doesn't mean a lot))
- tested that the other in-use cases that create ParenListExpr's
without a type don't lead to them being in the AST in the end
Rietveld link:
http://codereview.appspot.com/4584059/
Cheers,
/Manuel
Index: include/clang/AST/Expr.h
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index ce86458ed4f4d8e3f6b79a5d3f15833cdb375b25..fc1382ce1675a796f0124b28743e0621e14c64d0 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -3735,7 +3735,7 @@ class ParenListExpr : public Expr {
public:
ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs,
- unsigned numexprs, SourceLocation rparenloc);
+ unsigned numexprs, SourceLocation rparenloc, QualType T);
/// \brief Build an empty paren list.
explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
Index: lib/AST/Expr.cpp
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 987213907e4561c4b789f71a433f028677027ccc..ccf1d7f643eb8c94bb147c7c03e260a4afeb4d6c 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2960,8 +2960,8 @@ void DesignatedInitExpr::ExpandDesignator(ASTContext &C, unsigned Idx,
ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc,
Expr **exprs, unsigned nexprs,
- SourceLocation rparenloc)
- : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary,
+ SourceLocation rparenloc, QualType T)
+ : Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary,
false, false, false),
NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) {
Index: lib/Sema/SemaDeclCXX.cpp
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index ce99efbd0bd2020f702da71fc87a80d0b86759a8..a95ef69085526291eb7532aeb9788f68bab235f6 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1617,7 +1617,7 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr **Args,
// Can't check initialization for a member of dependent type or when
// any of the arguments are type-dependent expressions.
Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc);
+ RParenLoc, QualType());
// Erase any temporaries within this evaluation context; we're not
// going to track them in the AST, since we'll be rebuilding the
@@ -1659,7 +1659,7 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr **Args,
// and this approach is far more likely to get the corner cases right.
if (CurContext->isDependentContext())
Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc);
+ RParenLoc, QualType());
else
Init = MemberInit.get();
}
@@ -1715,22 +1715,7 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo,
if (DelegationInit.isInvalid())
return true;
- // If we are in a dependent context, template instantiation will
- // perform this type-checking again. Just save the arguments that we
- // received in a ParenListExpr.
- // FIXME: This isn't quite ideal, since our ASTs don't capture all
- // of the information that we have about the base
- // initializer. However, deconstructing the ASTs is a dicey process,
- // and this approach is far more likely to get the corner cases right.
- if (CurContext->isDependentContext()) {
- ExprResult Init
- = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args,
- NumArgs, RParenLoc));
- return new (Context) CXXCtorInitializer(Context, Loc, LParenLoc,
- Constructor, Init.takeAs<Expr>(),
- RParenLoc);
- }
-
+ assert(!CurContext->isDependentContext());
return new (Context) CXXCtorInitializer(Context, Loc, LParenLoc, Constructor,
DelegationInit.takeAs<Expr>(),
RParenLoc);
@@ -1815,7 +1800,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
// any of the arguments are type-dependent expressions.
ExprResult BaseInit
= Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc));
+ RParenLoc, QualType()));
// Erase any temporaries within this evaluation context; we're not
// going to track them in the AST, since we'll be rebuilding the
@@ -1878,7 +1863,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
if (CurContext->isDependentContext()) {
ExprResult Init
= Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc));
+ RParenLoc, QualType()));
return new (Context) CXXCtorInitializer(Context, BaseTInfo,
BaseSpec->isVirtual(),
LParenLoc,
@@ -7607,7 +7592,8 @@ void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
unsigned NumExprs = Exprs.size();
VDecl->setInit(new (Context) ParenListExpr(Context, LParenLoc,
(Expr **)Exprs.release(),
- NumExprs, RParenLoc));
+ NumExprs, RParenLoc,
+ VDecl->getType()));
return;
}
Index: lib/Sema/SemaExpr.cpp
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index a44b4475ce8b74337d1adf83ef1562d79ea0ac3a..75d1be7112c251dd11fc02dff2a779bc397d8768 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -5778,7 +5778,8 @@ ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
if (nexprs == 1 && TypeOfCast && !TypeIsVectorType(TypeOfCast))
expr = new (Context) ParenExpr(L, R, exprs[0]);
else
- expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R);
+ expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R,
+ QualType());
return Owned(expr);
}
Index: lib/Sema/SemaInit.cpp
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index a33f5d0b2f3ef530c689a2ddc28ebaef3074635e..f0d39893a449e62902f21160f10bd6a400353789 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -3684,19 +3684,9 @@ InitializationSequence::Perform(Sema &S,
}
}
-
- if (Kind.getKind() == InitializationKind::IK_Copy || Kind.isExplicitCast())
- return ExprResult(Args.release()[0]);
-
- if (Args.size() == 0)
- return S.Owned((Expr *)0);
-
- unsigned NumArgs = Args.size();
- return S.Owned(new (S.Context) ParenListExpr(S.Context,
- SourceLocation(),
- (Expr **)Args.release(),
- NumArgs,
- SourceLocation()));
+ assert(Kind.getKind() == InitializationKind::IK_Copy ||
+ Kind.isExplicitCast());
+ return ExprResult(Args.release()[0]);
}
// No steps means no initialization.
Index: test/Sema/paren-list-expr-type.cpp
diff --git a/test/Sema/paren-list-expr-type.cpp b/test/Sema/paren-list-expr-type.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ad5b7fbf918ea639630e29a4db0c15d4e14862b8
--- /dev/null
+++ b/test/Sema/paren-list-expr-type.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang -cc1 -ast-dump %s | not grep NULL
+// Makes sure that we don't introduce null types when handling
+// ParenListExpr.
+
+template<typename T> class X { void f() { X x(*this); } };
+
+template<typename T> class Y { Y() : t(1) {} T t; };
+
+template<typename T> class Z { Z() : b(true) {} const bool b; };
+
+template<typename T> class A : public Z<T> { A() : Z<T>() {} };
+
+class C {};
+template<typename T> class D : public C { D(): C() {} };
+
+void f() { (int)(1, 2); }
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits