diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2589,6 +2589,9 @@ NamedDecl *HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists); + bool tryToFixVariablyModifiedVarType(TypeSourceInfo *&TInfo, + QualType &T, SourceLocation Loc, + unsigned FailedFoldDiagID); void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S); bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info); bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6042,26 +6042,26 @@ /// Attempt to fold a variable-sized type to a constant-sized type, returning /// true if we were successful. -static bool tryToFixVariablyModifiedVarType(Sema &S, TypeSourceInfo *&TInfo, - QualType &T, SourceLocation Loc, - unsigned FailedFoldDiagID) { +bool Sema::tryToFixVariablyModifiedVarType(TypeSourceInfo *&TInfo, + QualType &T, SourceLocation Loc, + unsigned FailedFoldDiagID) { bool SizeIsNegative; llvm::APSInt Oversized; TypeSourceInfo *FixedTInfo = TryToFixInvalidVariablyModifiedTypeSourceInfo( - TInfo, S.Context, SizeIsNegative, Oversized); + TInfo, Context, SizeIsNegative, Oversized); if (FixedTInfo) { - S.Diag(Loc, diag::ext_vla_folded_to_constant); + Diag(Loc, diag::ext_vla_folded_to_constant); TInfo = FixedTInfo; T = FixedTInfo->getType(); return true; } if (SizeIsNegative) - S.Diag(Loc, diag::err_typecheck_negative_array_size); + Diag(Loc, diag::err_typecheck_negative_array_size); else if (Oversized.getBoolValue()) - S.Diag(Loc, diag::err_array_too_large) << Oversized.toString(10); + Diag(Loc, diag::err_array_too_large) << Oversized.toString(10); else if (FailedFoldDiagID) - S.Diag(Loc, FailedFoldDiagID); + Diag(Loc, FailedFoldDiagID); return false; } @@ -6910,10 +6910,10 @@ } } - // If this variable has a variable-modified type and an initializer, try to + // If this variable has a VLA type and an initializer, try to // fold to a constant-sized type. This is otherwise invalid. - if (D.hasInitializer() && R->isVariablyModifiedType()) - tryToFixVariablyModifiedVarType(*this, TInfo, R, D.getIdentifierLoc(), + if (D.hasInitializer() && R->isVariableArrayType()) + tryToFixVariablyModifiedVarType(TInfo, R, D.getIdentifierLoc(), /*DiagID=*/0); bool IsMemberSpecialization = false; @@ -16780,7 +16780,7 @@ // than a variably modified type. if (!InvalidDecl && T->isVariablyModifiedType()) { if (!tryToFixVariablyModifiedVarType( - *this, TInfo, T, Loc, diag::err_typecheck_field_variable_size)) + TInfo, T, Loc, diag::err_typecheck_field_variable_size)) InvalidDecl = true; } @@ -17008,7 +17008,7 @@ // than a variably modified type. else if (T->isVariablyModifiedType()) { if (!tryToFixVariablyModifiedVarType( - *this, TInfo, T, Loc, diag::err_typecheck_ivar_variable_size)) + TInfo, T, Loc, diag::err_typecheck_ivar_variable_size)) D.setInvalidType(); } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6874,9 +6874,12 @@ diag::err_array_incomplete_or_sizeless_type, SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd()))) return ExprError(); - if (literalType->isVariableArrayType()) - return ExprError(Diag(LParenLoc, diag::err_variable_object_no_init) - << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd())); + if (literalType->isVariableArrayType()) { + if (!tryToFixVariablyModifiedVarType(TInfo, literalType, LParenLoc, + diag::err_variable_object_no_init)) { + return ExprError(); + } + } } else if (!literalType->isDependentType() && RequireCompleteType(LParenLoc, literalType, diag::err_typecheck_decl_incomplete_type, diff --git a/clang/test/Sema/vla.c b/clang/test/Sema/vla.c --- a/clang/test/Sema/vla.c +++ b/clang/test/Sema/vla.c @@ -129,4 +129,9 @@ // expected-warning@+1{{variable length array folded to constant array as an extension}} char a8[2][ksize] = {{1,2,3,4},{4,3,2,1}}; + + // expected-warning@+1{{variable length array folded to constant array as an extension}} + char (*a9)[] = (char[2][ksize]) {{1,2,3,4},{4,3,2,1}}; + + char (*a10)[ksize] = 0; }