]> granicus.if.org Git - clang/commitdiff
Diagnose VLAs as an error in C++.
authorDouglas Gregor <dgregor@apple.com>
Fri, 11 Sep 2009 00:18:58 +0000 (00:18 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 11 Sep 2009 00:18:58 +0000 (00:18 +0000)
Also, treat the GNU __null as an integral constant expression to match
GCC's behavior.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81490 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/Expr.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaType.cpp
test/SemaCXX/c99.cpp [new file with mode: 0644]

index c9bfaaf55bcbdc6cbdb587251c275f0a2fd4f46c..f9f2f15af0628e26a93275421278380288fbd2ed 100644 (file)
@@ -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<
index 969098c2346255438addc347cbeda1adfd968695..fb79f4d0f244f9bf13ec0c65d613a5d98b8a9487 100644 (file)
@@ -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:
index d08d445911f5d63342a105610acdf93003156722..edf51cac6e7ea88131ee860a372cbf35971af6e2 100644 (file)
@@ -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),
index c4064e135eba905d6bd75825410a771e13c5eef5..9f951989a73f9cbb21a4f649247d6d957cdf9fec 100644 (file)
@@ -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/test/SemaCXX/c99.cpp b/test/SemaCXX/c99.cpp
new file mode 100644 (file)
index 0000000..b0ee056
--- /dev/null
@@ -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}}
+}