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
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5a2b2dc..56debcf 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -9308,6 +9308,8 @@
 }
 
 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 82bfe6f..363e2c4 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -4274,6 +4274,10 @@
   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 @@
                                                     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 0000000..00d63d0
--- /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 0000000..92873cb
--- /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}}
+}