Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -3784,6 +3784,7 @@ void DiscardCleanupsInEvaluationContext(); ExprResult TransformToPotentiallyEvaluated(Expr *E); + TypeSourceInfo *TransformToPotentiallyEvaluated(TypeSourceInfo *TInfo); ExprResult HandleExprEvaluationContextForTypeof(Expr *E); ExprResult ActOnConstantExpression(ExprResult Res); Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -4028,6 +4028,10 @@ } // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t. + if (isUnevaluatedContext() && ExprKind == UETT_SizeOf && + TInfo->getType()->isVariablyModifiedType()) + TInfo = TransformToPotentiallyEvaluated(TInfo); + return new (Context) UnaryExprOrTypeTraitExpr( ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd()); } @@ -13088,6 +13092,17 @@ return TransformToPE(*this).TransformExpr(E); } + +TypeSourceInfo *Sema::TransformToPotentiallyEvaluated(TypeSourceInfo *TInfo) { + assert(isUnevaluatedContext() && + "Should only transform unevaluated expressions"); + ExprEvalContexts.back().Context = + ExprEvalContexts[ExprEvalContexts.size()-2].Context; + if (isUnevaluatedContext()) + return TInfo; + return TransformToPE(*this).TransformType(TInfo); +} + void Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl, Index: test/SemaCXX/pr31042.cpp =================================================================== --- test/SemaCXX/pr31042.cpp +++ test/SemaCXX/pr31042.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -emit-obj -disable-free %s + +extern void abort (void); + +char a[1]; + +void +f1 (void) +{ + int i = 0; + int j = sizeof (typeof (*(char (*)[i])a)); +}