[cfe-commits] r81490 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Expr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaType.cpp test/SemaCXX/c99.cpp

Douglas Gregor dgregor at apple.com
Thu Sep 10 17:18:58 PDT 2009


Author: dgregor
Date: Thu Sep 10 19:18:58 2009
New Revision: 81490

URL: http://llvm.org/viewvc/llvm-project?rev=81490&view=rev
Log:
Diagnose VLAs as an error in C++.

Also, treat the GNU __null as an integral constant expression to match
GCC's behavior.

Added:
    cfe/trunk/test/SemaCXX/c99.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=81490&r1=81489&r2=81490&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 10 19:18:58 2009
@@ -67,6 +67,9 @@
 // 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 @@
   "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<

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=81490&r1=81489&r2=81490&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Sep 10 19:18:58 2009
@@ -1331,7 +1331,6 @@
   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 @@
   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:

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=81490&r1=81489&r2=81490&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Sep 10 19:18:58 2009
@@ -326,25 +326,31 @@
     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),

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=81490&r1=81489&r2=81490&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Sep 10 19:18:58 2009
@@ -593,9 +593,11 @@
     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;

Added: cfe/trunk/test/SemaCXX/c99.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/c99.cpp?rev=81490&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/c99.cpp (added)
+++ cfe/trunk/test/SemaCXX/c99.cpp Thu Sep 10 19:18:58 2009
@@ -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}}
+}





More information about the cfe-commits mailing list