summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-02-29 04:03:55 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-02-29 04:03:55 +0000
commit72b8b1ef9f7fb4f66fefcbd8d82fce2301b851d4 (patch)
tree4b46247b7ac7b97810ce8ad5d7e01d03679c46e6
parent5840dd9a09c458ef894e7d47caab1d90dc4c1112 (diff)
downloadclang-72b8b1ef9f7fb4f66fefcbd8d82fce2301b851d4.tar.gz
A couple minor bug-fixes for template instantiation for expressions which are sometimes potentially evaluated.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151707 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExpr.cpp2
-rw-r--r--lib/Sema/TreeTransform.h25
-rw-r--r--test/SemaTemplate/instantiate-sizeof.cpp10
-rw-r--r--test/SemaTemplate/instantiate-typeof.cpp10
4 files changed, 35 insertions, 12 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5a2b2dc7e9..56debcf208 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -9308,6 +9308,8 @@ namespace {
}
ExprResult Sema::TranformToPotentiallyEvaluated(Expr *E) {
+ assert(ExprEvalContexts.back().Context == Unevaluated &&
+ "Should only transform unevaluated expressions");
ExprEvalContexts.back().Context =
ExprEvalContexts[ExprEvalContexts.size()-2].Context;
if (ExprEvalContexts.back().Context == Unevaluated)
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 82bfe6fa70..363e2c408d 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -4274,6 +4274,10 @@ QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
if (E.isInvalid())
return QualType();
+ E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
+ if (E.isInvalid())
+ return QualType();
+
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() ||
E.get() != TL.getUnderlyingExpr()) {
@@ -6234,20 +6238,17 @@ TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
E->getSourceRange());
}
- ExprResult SubExpr;
- {
- // C++0x [expr.sizeof]p1:
- // The operand is either an expression, which is an unevaluated operand
- // [...]
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
+ // C++0x [expr.sizeof]p1:
+ // The operand is either an expression, which is an unevaluated operand
+ // [...]
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
- SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
- if (SubExpr.isInvalid())
- return ExprError();
+ ExprResult SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
+ if (SubExpr.isInvalid())
+ return ExprError();
- if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
- return SemaRef.Owned(E);
- }
+ if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
+ return SemaRef.Owned(E);
return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
E->getOperatorLoc(),
diff --git a/test/SemaTemplate/instantiate-sizeof.cpp b/test/SemaTemplate/instantiate-sizeof.cpp
new file mode 100644
index 0000000000..00d63d0c2f
--- /dev/null
+++ b/test/SemaTemplate/instantiate-sizeof.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// Make sure we handle contexts correctly with sizeof
+template<typename T> void f(T n) {
+ int buffer[n];
+ [] { int x = sizeof(sizeof(buffer)); }();
+}
+int main() {
+ f<int>(1);
+}
diff --git a/test/SemaTemplate/instantiate-typeof.cpp b/test/SemaTemplate/instantiate-typeof.cpp
new file mode 100644
index 0000000000..92873cb4b0
--- /dev/null
+++ b/test/SemaTemplate/instantiate-typeof.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// Make sure we correctly treat __typeof as potentially-evaluated when appropriate
+template<typename T> void f(T n) {
+ int buffer[n]; // expected-note {{declared here}}
+ [] { __typeof(buffer) x; }(); // expected-error {{variable 'buffer' with variably modified type cannot be captured in a lambda expression}}
+}
+int main() {
+ f<int>(1); // expected-note {{in instantiation}}
+}