summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-09-26 04:34:21 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-09-26 04:34:21 +0000
commit15681d6852d8990a714ec3f5b202978e927b09cc (patch)
tree2bf0faf2b8a421d766ea3a4b849aa699888d9280
parent81406f692fe0f2f7983ebe9194c25f65b56e7a13 (diff)
downloadbcm5719-llvm-15681d6852d8990a714ec3f5b202978e927b09cc.tar.gz
bcm5719-llvm-15681d6852d8990a714ec3f5b202978e927b09cc.zip
Fix an edge case of mangling involving the combination of a lambda and typeid.
typeid (and a couple other non-standard places where we can transform an unevaluated expression into an evaluated expression) is special because it introduces an an expression evaluation context, which conflicts with the mechanism to compute the current lambda mangling context. PR12123. I would appreciate if someone would double-check that we get the mangling correct with this patch. llvm-svn: 164658
-rw-r--r--clang/include/clang/Sema/Sema.h14
-rw-r--r--clang/lib/Parse/ParseDecl.cpp3
-rw-r--r--clang/lib/Parse/ParseExpr.cpp3
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp8
-rw-r--r--clang/lib/Sema/TreeTransform.h9
-rw-r--r--clang/test/CodeGenCXX/mangle-lambdas.cpp13
7 files changed, 46 insertions, 7 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 676f52953f3..97d425ceaea 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2721,7 +2721,10 @@ public:
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
Decl *LambdaContextDecl = 0,
bool IsDecltype = false);
-
+ enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl };
+ void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
+ ReuseLambdaContextDecl_t,
+ bool IsDecltype = false);
void PopExpressionEvaluationContext();
void DiscardCleanupsInEvaluationContext();
@@ -7295,6 +7298,15 @@ public:
Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
IsDecltype);
}
+ EnterExpressionEvaluationContext(Sema &Actions,
+ Sema::ExpressionEvaluationContext NewContext,
+ Sema::ReuseLambdaContextDecl_t,
+ bool IsDecltype = false)
+ : Actions(Actions) {
+ Actions.PushExpressionEvaluationContext(NewContext,
+ Sema::ReuseLambdaContextDecl,
+ IsDecltype);
+ }
~EnterExpressionEvaluationContext() {
Actions.PopExpressionEvaluationContext();
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index f8a20c3b532..674cd2d22f0 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5078,7 +5078,8 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
const bool hasParens = Tok.is(tok::l_paren);
- EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
+ Sema::ReuseLambdaContextDecl);
bool isCastExpr;
ParsedType CastTy;
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 37cdd14407f..90373920c5d 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1723,7 +1723,8 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
if (OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof))
Diag(OpTok, diag::warn_cxx98_compat_alignof);
- EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
+ Sema::ReuseLambdaContextDecl);
bool isCastExpr;
ParsedType CastTy;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 3039368cf7b..41bf1b623f6 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1001,7 +1001,8 @@ ExprResult Parser::ParseCXXTypeid() {
// We enter the unevaluated context before trying to determine whether we
// have a type-id, because the tentative parse logic will try to resolve
// names, and must treat them as unevaluated.
- EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
+ Sema::ReuseLambdaContextDecl);
if (isTypeIdInParens()) {
TypeResult Ty = ParseTypeName();
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 41985328bb7..630281a4242 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10135,6 +10135,14 @@ Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs);
}
+void
+Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
+ ReuseLambdaContextDecl_t,
+ bool IsDecltype) {
+ Decl *LambdaContextDecl = ExprEvalContexts.back().LambdaContextDecl;
+ PushExpressionEvaluationContext(NewContext, LambdaContextDecl, IsDecltype);
+}
+
void Sema::PopExpressionEvaluationContext() {
ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back();
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 975895dc8e0..e0451c4c49f 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4275,7 +4275,8 @@ template<typename Derived>
QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
TypeOfExprTypeLoc TL) {
// typeof expressions are not potentially evaluated contexts
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated,
+ Sema::ReuseLambdaContextDecl);
ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
if (E.isInvalid())
@@ -6266,7 +6267,8 @@ TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
// C++0x [expr.sizeof]p1:
// The operand is either an expression, which is an unevaluated operand
// [...]
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated,
+ Sema::ReuseLambdaContextDecl);
ExprResult SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
if (SubExpr.isInvalid())
@@ -7002,7 +7004,8 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
// after we perform semantic analysis. We speculatively assume it is
// unevaluated; it will get fixed later if the subexpression is in fact
// potentially evaluated.
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated,
+ Sema::ReuseLambdaContextDecl);
ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
if (SubExpr.isInvalid())
diff --git a/clang/test/CodeGenCXX/mangle-lambdas.cpp b/clang/test/CodeGenCXX/mangle-lambdas.cpp
index 979760dab91..0bd5ad2a02c 100644
--- a/clang/test/CodeGenCXX/mangle-lambdas.cpp
+++ b/clang/test/CodeGenCXX/mangle-lambdas.cpp
@@ -172,6 +172,19 @@ template<typename...T> int PR12917<T...>::n[3] = {
PR12917<int, char, double> pr12917;
int *pr12917_p = PR12917<int, int>::n;
+namespace std {
+ struct type_info;
+}
+namespace PR12123 {
+ struct A { virtual ~A(); } g;
+ struct B {
+ void f(const std::type_info& x = typeid([]()->A& { return g; }()));
+ void h();
+ };
+ void B::h() { f(); }
+}
+// CHECK: define linkonce_odr %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv
+
namespace PR12808 {
template <typename> struct B {
int a;
OpenPOWER on IntegriCloud