diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-02-29 04:03:55 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-02-29 04:03:55 +0000 |
commit | 72b8b1ef9f7fb4f66fefcbd8d82fce2301b851d4 (patch) | |
tree | 4b46247b7ac7b97810ce8ad5d7e01d03679c46e6 | |
parent | 5840dd9a09c458ef894e7d47caab1d90dc4c1112 (diff) | |
download | clang-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.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 25 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-sizeof.cpp | 10 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-typeof.cpp | 10 |
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}} +} |