Index: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3864,6 +3864,8 @@ if (Body.isInvalid()) Function->setInvalidDecl(); + // FIXME: finishing the function body while in an expression evaluation + // context seems wrong. Investigate more. ActOnFinishFunctionBody(Function, Body.get(), /*IsInstantiation=*/true); Index: cfe/trunk/lib/Sema/TreeTransform.h =================================================================== --- cfe/trunk/lib/Sema/TreeTransform.h +++ cfe/trunk/lib/Sema/TreeTransform.h @@ -4603,8 +4603,15 @@ if (ElementType.isNull()) return QualType(); - ExprResult SizeResult - = getDerived().TransformExpr(T->getSizeExpr()); + ExprResult SizeResult; + { + EnterExpressionEvaluationContext Context(SemaRef, + Sema::PotentiallyEvaluated); + SizeResult = getDerived().TransformExpr(T->getSizeExpr()); + } + if (SizeResult.isInvalid()) + return QualType(); + SizeResult = SemaRef.ActOnFinishFullExpr(SizeResult.get()); if (SizeResult.isInvalid()) return QualType(); Index: cfe/trunk/test/Sema/pr30306.cpp =================================================================== --- cfe/trunk/test/Sema/pr30306.cpp +++ cfe/trunk/test/Sema/pr30306.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -x c++ -emit-llvm < %s | FileCheck %s + +struct A { A(int); ~A(); }; +int f(const A &); +// CHECK: call void @_ZN1AC1Ei +// CHECK-NEXT: call i32 @_Z1fRK1A +// CHECK-NEXT: call void @_ZN1AD1Ev +// CHECK: call void @_ZN1AC1Ei +// CHECK-NEXT: call i32 @_Z1fRK1A +// CHECK-NEXT: call void @_ZN1AD1Ev +template void g() { + int a[f(3)]; + int b[f(3)]; +} +int main() { g(); }