[cfe-commits] r113778 - in /cfe/trunk: include/clang/AST/ExprCXX.h include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprCXX.cpp lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp test/CodeGenCXX/delete.cpp test/SemaCXX/delete.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Mon Sep 13 13:15:54 PDT 2010


Author: akirtzidis
Date: Mon Sep 13 15:15:54 2010
New Revision: 113778

URL: http://llvm.org/viewvc/llvm-project?rev=113778&view=rev
Log:
When applying 'delete' on a pointer-to-array type match GCC and EDG behavior and treat it as 'delete[]'.
Also offer a fix-it hint adding '[]'.

Added:
    cfe/trunk/test/SemaCXX/delete.cpp
Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
    cfe/trunk/test/CodeGenCXX/delete.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=113778&r1=113777&r2=113778&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Mon Sep 13 15:15:54 2010
@@ -1107,6 +1107,10 @@
   bool GlobalDelete : 1;
   // Is this the array form of delete, i.e. "delete[]"?
   bool ArrayForm : 1;
+  // ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied
+  // to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm
+  // will be true).
+  bool ArrayFormAsWritten : 1;
   // Points to the operator delete overload that is used. Could be a member.
   FunctionDecl *OperatorDelete;
   // The pointer expression to be deleted.
@@ -1115,15 +1119,17 @@
   SourceLocation Loc;
 public:
   CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm,
-                FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc)
+                bool arrayFormAsWritten, FunctionDecl *operatorDelete,
+                Expr *arg, SourceLocation loc)
     : Expr(CXXDeleteExprClass, ty, false, false), GlobalDelete(globalDelete),
-      ArrayForm(arrayForm), OperatorDelete(operatorDelete), Argument(arg),
-      Loc(loc) { }
+      ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
+      OperatorDelete(operatorDelete), Argument(arg), Loc(loc) { }
   explicit CXXDeleteExpr(EmptyShell Shell)
     : Expr(CXXDeleteExprClass, Shell), OperatorDelete(0), Argument(0) { }
 
   bool isGlobalDelete() const { return GlobalDelete; }
   bool isArrayForm() const { return ArrayForm; }
+  bool isArrayFormAsWritten() const { return ArrayFormAsWritten; }
 
   FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=113778&r1=113777&r2=113778&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Sep 13 15:15:54 2010
@@ -2448,6 +2448,8 @@
   "deleting pointer to incomplete type %0 may cause undefined behaviour">;
 def err_delete_incomplete_class_type : Warning<
   "deleting incomplete class type %0; no conversions to pointer type">;
+def warn_delete_array_type : Warning<
+  "'delete' applied to a pointer-to-array type %0 treated as delete[]">;
 def err_no_suitable_delete_member_function_found : Error<
   "no suitable member %0 in %1">;
 def err_ambiguous_suitable_delete_member_function_found : Error<

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=113778&r1=113777&r2=113778&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Sep 13 15:15:54 2010
@@ -1438,6 +1438,7 @@
   // DR599 amends "pointer type" to "pointer to object type" in both cases.
 
   FunctionDecl *OperatorDelete = 0;
+  bool ArrayFormAsWritten = ArrayForm;
 
   if (!Ex->isTypeDependent()) {
     QualType Type = Ex->getType();
@@ -1514,7 +1515,14 @@
     //   of the delete-expression. ]
     ImpCastExprToType(Ex, Context.getPointerType(Context.VoidTy), 
                       CK_NoOp);
-    
+
+    if (Pointee->isArrayType() && !ArrayForm) {
+      Diag(StartLoc, diag::warn_delete_array_type)
+          << Type << Ex->getSourceRange()
+          << FixItHint::CreateInsertion(PP.getLocForEndOfToken(StartLoc), "[]");
+      ArrayForm = true;
+    }
+
     DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
                                       ArrayForm ? OO_Array_Delete : OO_Delete);
 
@@ -1548,7 +1556,8 @@
   }
 
   return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm,
-                                           OperatorDelete, Ex, StartLoc));
+                                           ArrayFormAsWritten, OperatorDelete,
+                                           Ex, StartLoc));
 }
 
 /// \brief Check the use of the given variable as a C++ condition in an if,

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=113778&r1=113777&r2=113778&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Sep 13 15:15:54 2010
@@ -1112,6 +1112,7 @@
   VisitExpr(E);
   E->GlobalDelete = Record[Idx++];
   E->ArrayForm = Record[Idx++];
+  E->ArrayFormAsWritten = Record[Idx++];
   E->OperatorDelete = cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
   E->Argument = Reader.ReadSubExpr();
   E->Loc = Reader.ReadSourceLocation(Record, Idx);

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=113778&r1=113777&r2=113778&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Sep 13 15:15:54 2010
@@ -1121,6 +1121,7 @@
   VisitExpr(E);
   Record.push_back(E->isGlobalDelete());
   Record.push_back(E->isArrayForm());
+  Record.push_back(E->isArrayFormAsWritten());
   Writer.AddDeclRef(E->getOperatorDelete(), Record);
   Writer.AddStmt(E->getArgument());
   Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);

Modified: cfe/trunk/test/CodeGenCXX/delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/delete.cpp?rev=113778&r1=113777&r2=113778&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/delete.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/delete.cpp Mon Sep 13 15:15:54 2010
@@ -105,3 +105,10 @@
     delete [] b;
   }
 }
+
+namespace test3 {
+  void f(int a[10][20]) {
+    // CHECK: call void @_ZdaPv(i8*
+    delete a;
+  }
+}

Added: cfe/trunk/test/SemaCXX/delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/delete.cpp?rev=113778&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/delete.cpp (added)
+++ cfe/trunk/test/SemaCXX/delete.cpp Mon Sep 13 15:15:54 2010
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: %clang_cc1 -fixit -x c++ %t
+// RUN: FileCheck -input-file=%t %s
+
+void f(int a[10][20]) {
+  // CHECK: delete[] a;
+  delete a; // expected-warning {{'delete' applied to a pointer-to-array type}}
+}





More information about the cfe-commits mailing list