]> granicus.if.org Git - clang/commitdiff
A couple minor bug-fixes for template instantiation for expressions which are sometim...
authorEli Friedman <eli.friedman@gmail.com>
Wed, 29 Feb 2012 04:03:55 +0000 (04:03 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 29 Feb 2012 04:03:55 +0000 (04:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151707 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
lib/Sema/TreeTransform.h
test/SemaTemplate/instantiate-sizeof.cpp [new file with mode: 0644]
test/SemaTemplate/instantiate-typeof.cpp [new file with mode: 0644]

index 5a2b2dc7e90f5c07f980a6b56cdcd51bd9e9e34b..56debcf208727e32c2779be6eee3deb9ac8f08dd 100644 (file)
@@ -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)
index 82bfe6fa7063739b1b021c8ef3492e4265c7766e..363e2c408db65ba21417dda654f427ace3d802ad 100644 (file)
@@ -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 (file)
index 0000000..00d63d0
--- /dev/null
@@ -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 (file)
index 0000000..92873cb
--- /dev/null
@@ -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}}
+}