diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 6 | ||||
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 32 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 6 | ||||
| -rw-r--r-- | clang/test/SemaCXX/c99.cpp | 8 |
5 files changed, 41 insertions, 16 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index c9bfaaf55bc..f9f2f15af06 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -67,6 +67,9 @@ def ext_flexible_array_init : Extension< // Declarations. def ext_vla : Extension< "variable length arrays are a C99 feature, accepted as an extension">; +def err_vla_cxx : Error< + "variable length arrays are not permitted in C++">; + def ext_anon_param_requires_type_specifier : Extension< "type specifier required for unnamed parameter, defaults to int">; def err_bad_variable_name : Error< @@ -2135,6 +2138,9 @@ def err_objc_array_of_interfaces : Error< "array of interface %0 is invalid (probably should be an array of pointers)">; def ext_c99_array_usage : Extension< "use of C99-specific array features, accepted as an extension">; +def err_c99_array_usage_cxx : Error< + "C99-specific array features are not permitted in C++">; + def err_invalid_protocol_qualifiers : Error< "invalid protocol qualifiers on non-ObjC type">; def warn_ivar_use_hidden : Warning< diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 969098c2346..fb79f4d0f24 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1331,7 +1331,6 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::VAArgExprClass: case Expr::AddrLabelExprClass: case Expr::StmtExprClass: - case Expr::GNUNullExprClass: case Expr::CXXMemberCallExprClass: case Expr::CXXDynamicCastExprClass: case Expr::CXXTypeidExprClass: @@ -1368,6 +1367,10 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::ExprClass: return ICEDiag(2, E->getLocStart()); + case Expr::GNUNullExprClass: + // GCC considers the GNU __null value to be an integral constant expression. + return NoDiag(); + case Expr::ParenExprClass: return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx); case Expr::IntegerLiteralClass: diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index d08d445911f..edf51cac6e7 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -326,25 +326,31 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, Skip = 1; } + // Every dimension shall be of constant size. + if (D.getNumTypeObjects() > 0 && + D.getTypeObject(0).Kind == DeclaratorChunk::Array) { + for (unsigned I = 1, N = D.getNumTypeObjects(); I < N; ++I) { + if (D.getTypeObject(I).Kind != DeclaratorChunk::Array) + break; + + DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr; + if (Expr *NumElts = (Expr *)Array.NumElts) { + if (!NumElts->isTypeDependent() && !NumElts->isValueDependent() && + !NumElts->isIntegerConstantExpr(Context)) { + Diag(D.getTypeObject(I).Loc, diag::err_new_array_nonconst) + << NumElts->getSourceRange(); + return ExprError(); + } + } + } + } + //FIXME: Store DeclaratorInfo in CXXNew expression. DeclaratorInfo *DInfo = 0; QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo, Skip); if (D.isInvalidType()) return ExprError(); - // Every dimension shall be of constant size. - unsigned i = 1; - QualType ElementType = AllocType; - while (const ArrayType *Array = Context.getAsArrayType(ElementType)) { - if (!Array->isConstantArrayType()) { - Diag(D.getTypeObject(i).Loc, diag::err_new_array_nonconst) - << static_cast<Expr*>(D.getTypeObject(i).Arr.NumElts)->getSourceRange(); - return ExprError(); - } - ElementType = Array->getElementType(); - ++i; - } - return BuildCXXNew(StartLoc, UseGlobal, PlacementLParen, move(PlacementArgs), diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index c4064e135eb..9f951989a73 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -593,9 +593,11 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, if (ArraySize && !ArraySize->isTypeDependent() && !ArraySize->isValueDependent() && !ArraySize->isIntegerConstantExpr(Context)) - Diag(Loc, diag::ext_vla); + Diag(Loc, getLangOptions().CPlusPlus? diag::err_vla_cxx : diag::ext_vla); else if (ASM != ArrayType::Normal || Quals != 0) - Diag(Loc, diag::ext_c99_array_usage); + Diag(Loc, + getLangOptions().CPlusPlus? diag::err_c99_array_usage_cxx + : diag::ext_c99_array_usage); } return T; diff --git a/clang/test/SemaCXX/c99.cpp b/clang/test/SemaCXX/c99.cpp new file mode 100644 index 00000000000..b0ee056ef37 --- /dev/null +++ b/clang/test/SemaCXX/c99.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void f0(int i) { + char array[i]; // expected-error{{variable length arrays}} +} + +void f1(int i[static 5]) { // expected-error{{C99}} +} |

