From b34d0ef2caa6beb1a1005e55f8855c8d8080f4c4 Mon Sep 17 00:00:00 2001 From: Tim Shen Date: Tue, 14 Feb 2017 23:46:37 +0000 Subject: [PATCH] [VLA] Handle VLA size expression in a full-expression context. Summary: Previously the cleanups (e.g. dtor calls) are inserted into the outer scope (e.g. function body scope), instead of it's own scope. After the fix, the cleanups are inserted right after getting the size value. This fixes pr30306. Reviewers: rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D24333 llvm-svn: 295123 --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 ++ clang/lib/Sema/TreeTransform.h | 11 +++++++++-- clang/test/Sema/pr30306.cpp | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 clang/test/Sema/pr30306.cpp diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index a0e4d2999d9f..f7db189de849 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3864,6 +3864,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, 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); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index ef349c395f8a..8a63d3547464 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -4603,8 +4603,15 @@ TreeTransform::TransformVariableArrayType(TypeLocBuilder &TLB, 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(); diff --git a/clang/test/Sema/pr30306.cpp b/clang/test/Sema/pr30306.cpp new file mode 100644 index 000000000000..7442377dc51a --- /dev/null +++ b/clang/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(); }