From: Douglas Gregor Date: Wed, 6 Oct 2010 16:00:31 +0000 (+0000) Subject: Reject the allocation of variably-modified types in C++ 'new' X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a0750768718bb5d05150641b5bba74847a21bc09;p=clang Reject the allocation of variably-modified types in C++ 'new' expressions. Fixes PR8209 in the narrowest way possible. I'm still considering whether I want to implement the extension that permits the use of VLA types in a 'new' expression. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115790 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index fafce83b9a..c6582d9ace 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -46,12 +46,14 @@ def err_vla_decl_has_static_storage : Error< "variable length array declaration can not have 'static' storage duration">; def err_vla_decl_has_extern_linkage : Error< "variable length array declaration can not have 'extern' linkage">; - + // C99 variably modified types def err_variably_modified_template_arg : Error< "variably modified type %0 cannot be used as a template argument">; def err_variably_modified_nontype_template_param : Error< "non-type template parameter of variably modified type %0">; +def err_variably_modified_new_type : Error< + "'new' cannot allocate object of variably modified type %0">; // C99 Designated Initializers def err_array_designator_negative : Error< diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index e4ee90d668..c674031219 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -711,8 +711,6 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, MultiExprArg ConstructorArgs, SourceLocation ConstructorRParen) { SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange(); - if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange)) - return ExprError(); // Per C++0x [expr.new]p5, the type being constructed may be a // typedef of an array type. @@ -726,6 +724,9 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, } } + if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange)) + return ExprError(); + QualType ResultType = Context.getPointerType(AllocType); // C++ 5.3.4p6: "The expression in a direct-new-declarator shall have integral @@ -930,7 +931,10 @@ bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc, else if (RequireNonAbstractType(Loc, AllocType, diag::err_allocation_of_abstract_type)) return true; - + else if (AllocType->isVariablyModifiedType()) + return Diag(Loc, diag::err_variably_modified_new_type) + << AllocType; + return false; } diff --git a/test/SemaCXX/c99-variable-length-array.cpp b/test/SemaCXX/c99-variable-length-array.cpp index 7dc912a0d5..98df1dbfe8 100644 --- a/test/SemaCXX/c99-variable-length-array.cpp +++ b/test/SemaCXX/c99-variable-length-array.cpp @@ -114,3 +114,10 @@ namespace rdar8021385 { }; B a; } + +namespace PR8209 { + void f(int n) { + typedef int vla_type[n]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}} + (void)new vla_type; // expected-error{{variably}} + } +}