r237391 - Revert "Detect uses of mismatching forms of 'new' and 'delete'"
Diego Novillo
dnovillo at google.com
Thu May 14 13:57:48 PDT 2015
Author: dnovillo
Date: Thu May 14 15:57:48 2015
New Revision: 237391
URL: http://llvm.org/viewvc/llvm-project?rev=237391&view=rev
Log:
Revert "Detect uses of mismatching forms of 'new' and 'delete'"
This reverts commit 742dc9b6c9686ab52860b7da39c3a126d8a97fbc.
This is generating multiple segfaults in our internal builds.
Test case coming up shortly.
Removed:
cfe/trunk/test/SemaCXX/delete-mismatch.h
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/ExternalSemaSource.h
cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/include/clang/Serialization/ASTBitCodes.h
cfe/trunk/include/clang/Serialization/ASTReader.h
cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
cfe/trunk/test/Analysis/MismatchedDeallocator-checker-test.mm
cfe/trunk/test/Analysis/MismatchedDeallocator-path-notes.cpp
cfe/trunk/test/CodeGenCXX/new.cpp
cfe/trunk/test/SemaCXX/delete.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 14 15:57:48 2015
@@ -5510,12 +5510,7 @@ def err_delete_explicit_conversion : Err
"conversion function">;
def note_delete_conversion : Note<"conversion to pointer type %0">;
def warn_delete_array_type : Warning<
- "'delete' applied to a pointer-to-array type %0 treated as 'delete[]'">;
-def warn_mismatched_delete_new : Warning<
- "'delete%select{|[]}0' applied to a pointer that was allocated with "
- "'new%select{[]|}0'; did you mean 'delete%select{[]|}0'?">,
- InGroup<DiagGroup<"mismatched-new-delete">>;
-def note_allocated_here : Note<"allocated with 'new%select{[]|}0' here">;
+ "'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/include/clang/Sema/ExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ExternalSemaSource.h?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/ExternalSemaSource.h Thu May 14 15:57:48 2015
@@ -27,7 +27,6 @@ template <class T, unsigned n> class Sma
namespace clang {
class CXXConstructorDecl;
-class CXXDeleteExpr;
class CXXRecordDecl;
class DeclaratorDecl;
class LookupResult;
@@ -80,9 +79,6 @@ public:
virtual void ReadUndefinedButUsed(
llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined);
- virtual void ReadMismatchingDeleteExpressions(llvm::MapVector<
- FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &);
-
/// \brief Do last resort, unqualified lookup on a LookupResult that
/// Sema cannot find.
///
Modified: cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h Thu May 14 15:57:48 2015
@@ -230,10 +230,6 @@ public:
void ReadUndefinedButUsed(
llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) override;
- void ReadMismatchingDeleteExpressions(llvm::MapVector<
- FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
- Exprs) override;
-
/// \brief Do last resort, unqualified lookup on a LookupResult that
/// Sema cannot find.
///
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu May 14 15:57:48 2015
@@ -78,7 +78,6 @@ namespace clang {
typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
class CXXConstructorDecl;
class CXXConversionDecl;
- class CXXDeleteExpr;
class CXXDestructorDecl;
class CXXFieldCollector;
class CXXMemberCallExpr;
@@ -403,15 +402,6 @@ public:
llvm::SmallSetVector<const TypedefNameDecl *, 4>
UnusedLocalTypedefNameCandidates;
- /// \brief Delete-expressions to be analyzed at the end of translation unit
- ///
- /// This list contains class members, and locations of delete-expressions
- /// that could not be proven as to whether they mismatch with new-expression
- /// used in initializer of the field.
- typedef std::pair<SourceLocation, bool> DeleteExprLoc;
- typedef llvm::SmallVector<DeleteExprLoc, 4> DeleteLocs;
- llvm::MapVector<FieldDecl *, DeleteLocs> DeleteExprs;
-
typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy;
/// PureVirtualClassDiagSet - a set of class declarations which we have
@@ -896,11 +886,6 @@ public:
void getUndefinedButUsed(
SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined);
- /// Retrieves list of suspicious delete-expressions that will be checked at
- /// the end of translation unit.
- const llvm::MapVector<FieldDecl *, DeleteLocs> &
- getMismatchingDeleteExpressions() const;
-
typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods;
typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool;
@@ -8654,9 +8639,6 @@ private:
/// attempts to add itself into the container
void CheckObjCCircularContainer(ObjCMessageExpr *Message);
- void AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE);
- void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,
- bool DeleteWasArrayForm);
public:
/// \brief Register a magic integral constant to be used as a type tag.
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind,
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Thu May 14 15:57:48 2015
@@ -561,9 +561,6 @@ namespace clang {
/// \brief Record code for the table of offsets to CXXCtorInitializers
/// lists.
CXX_CTOR_INITIALIZERS_OFFSETS = 53,
-
- /// \brief Delete expressions that will be analyzed later.
- DELETE_EXPRS_TO_ANALYZE = 54
};
/// \brief Record types used within a source manager block.
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Thu May 14 15:57:48 2015
@@ -756,9 +756,6 @@ private:
/// SourceLocation of a matching ODR-use.
SmallVector<uint64_t, 8> UndefinedButUsed;
- /// \brief Delete expressions to analyze at the end of translation unit.
- SmallVector<uint64_t, 8> DelayedDeleteExprs;
-
// \brief A list of late parsed template function data.
SmallVector<uint64_t, 1> LateParsedTemplates;
@@ -1739,10 +1736,6 @@ public:
void ReadUndefinedButUsed(
llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) override;
- void ReadMismatchingDeleteExpressions(llvm::MapVector<
- FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
- Exprs);
-
void ReadTentativeDefinitions(
SmallVectorImpl<VarDecl *> &TentativeDefs) override;
Modified: cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp (original)
+++ cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp Thu May 14 15:57:48 2015
@@ -212,15 +212,7 @@ void MultiplexExternalSemaSource::ReadUn
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadUndefinedButUsed(Undefined);
}
-
-void MultiplexExternalSemaSource::ReadMismatchingDeleteExpressions(
- llvm::MapVector<FieldDecl *,
- llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
- Exprs) {
- for (auto &Source : Sources)
- Source->ReadMismatchingDeleteExpressions(Exprs);
-}
-
+
bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult &R, Scope *S){
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->LookupUnqualified(R, S);
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu May 14 15:57:48 2015
@@ -860,17 +860,6 @@ void Sema::ActOnEndOfTranslationUnit() {
}
}
- if (!Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation())) {
- if (ExternalSource)
- ExternalSource->ReadMismatchingDeleteExpressions(DeleteExprs);
- for (const auto &DeletedFieldInfo : DeleteExprs) {
- for (const auto &DeleteExprLoc : DeletedFieldInfo.second) {
- AnalyzeDeleteExprMismatch(DeletedFieldInfo.first, DeleteExprLoc.first,
- DeleteExprLoc.second);
- }
- }
- }
-
// Check we've noticed that we're no longer parsing the initializer for every
// variable. If we miss cases, then at best we have a performance issue and
// at worst a rejects-valid bug.
@@ -1230,9 +1219,6 @@ void ExternalSemaSource::ReadUndefinedBu
llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) {
}
-void ExternalSemaSource::ReadMismatchingDeleteExpressions(llvm::MapVector<
- FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &) {}
-
void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const {
SourceLocation Loc = this->Loc;
if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation();
@@ -1481,8 +1467,3 @@ CapturedRegionScopeInfo *Sema::getCurCap
return dyn_cast<CapturedRegionScopeInfo>(FunctionScopes.back());
}
-
-const llvm::MapVector<FieldDecl *, Sema::DeleteLocs> &
-Sema::getMismatchingDeleteExpressions() const {
- return DeleteExprs;
-}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu May 14 15:57:48 2015
@@ -2339,261 +2339,6 @@ bool Sema::FindDeallocationFunction(Sour
return false;
}
-namespace {
-/// \brief Checks whether delete-expression, and new-expression used for
-/// initializing deletee have the same array form.
-class MismatchingNewDeleteDetector {
-public:
- enum MismatchResult {
- /// Indicates that there is no mismatch or a mismatch cannot be proven.
- NoMismatch,
- /// Indicates that variable is initialized with mismatching form of \a new.
- VarInitMismatches,
- /// Indicates that member is initialized with mismatching form of \a new.
- MemberInitMismatches,
- /// Indicates that 1 or more constructors' definitions could not been
- /// analyzed, and they will be checked again at the end of translation unit.
- AnalyzeLater
- };
-
- /// \param EndOfTU True, if this is the final analysis at the end of
- /// translation unit. False, if this is the initial analysis at the point
- /// delete-expression was encountered.
- explicit MismatchingNewDeleteDetector(bool EndOfTU)
- : IsArrayForm(false), Field(nullptr), EndOfTU(EndOfTU),
- HasUndefinedConstructors(false) {}
-
- /// \brief Checks whether pointee of a delete-expression is initialized with
- /// matching form of new-expression.
- ///
- /// If return value is \c VarInitMismatches or \c MemberInitMismatches at the
- /// point where delete-expression is encountered, then a warning will be
- /// issued immediately. If return value is \c AnalyzeLater at the point where
- /// delete-expression is seen, then member will be analyzed at the end of
- /// translation unit. \c AnalyzeLater is returned iff at least one constructor
- /// couldn't be analyzed. If at least one constructor initializes the member
- /// with matching type of new, the return value is \c NoMismatch.
- MismatchResult analyzeDeleteExpr(const CXXDeleteExpr *DE);
- /// \brief Analyzes a class member.
- /// \param Field Class member to analyze.
- /// \param DeleteWasArrayForm Array form-ness of the delete-expression used
- /// for deleting the \p Field.
- MismatchResult analyzeField(FieldDecl *Field, bool DeleteWasArrayForm);
- /// List of mismatching new-expressions used for initialization of the pointee
- llvm::SmallVector<const CXXNewExpr *, 4> NewExprs;
- /// Indicates whether delete-expression was in array form.
- bool IsArrayForm;
- FieldDecl *Field;
-
-private:
- const bool EndOfTU;
- /// \brief Indicates that there is at least one constructor without body.
- bool HasUndefinedConstructors;
- /// \brief Returns \c CXXNewExpr from given initialization expression.
- /// \param E Expression used for initializing pointee in delete-expression.
- /// \param E can be a single-element \c InitListExpr consisting of
- /// \param E new-expression.
- const CXXNewExpr *getNewExprFromInitListOrExpr(const Expr *E);
- /// \brief Returns whether member is initialized with mismatching form of
- /// \c new either by the member initializer or in-class initialization.
- ///
- /// If bodies of all constructors are not visible at the end of translation
- /// unit or at least one constructor initializes member with the matching
- /// form of \c new, mismatch cannot be proven, and this function will return
- /// \c NoMismatch.
- MismatchResult analyzeMemberExpr(const MemberExpr *ME);
- /// \brief Returns whether variable is initialized with mismatching form of
- /// \c new.
- ///
- /// If variable is initialized with matching form of \c new or variable is not
- /// initialized with a \c new expression, this function will return true.
- /// If variable is initialized with mismatching form of \c new, returns false.
- /// \param D Variable to analyze.
- bool hasMatchingVarInit(const DeclRefExpr *D);
- /// \brief Checks whether the constructor initializes pointee with mismatching
- /// form of \c new.
- ///
- /// Returns true, if member is initialized with matching form of \c new in
- /// member initializer list. Returns false, if member is initialized with the
- /// matching form of \c new in this constructor's initializer or given
- /// constructor isn't defined at the point where delete-expression is seen, or
- /// member isn't initialized by the constructor.
- bool hasMatchingNewInCtor(const CXXConstructorDecl *CD);
- /// \brief Checks whether member is initialized with matching form of
- /// \c new in member initializer list.
- bool hasMatchingNewInCtorInit(const CXXCtorInitializer *CI);
- /// Checks whether member is initialized with mismatching form of \c new by
- /// in-class initializer.
- MismatchResult analyzeInClassInitializer();
-};
-}
-
-MismatchingNewDeleteDetector::MismatchResult
-MismatchingNewDeleteDetector::analyzeDeleteExpr(const CXXDeleteExpr *DE) {
- NewExprs.clear();
- assert(DE && "Expected delete-expression");
- IsArrayForm = DE->isArrayForm();
- const Expr *E = DE->getArgument()->IgnoreParenImpCasts();
- if (const MemberExpr *ME = dyn_cast<const MemberExpr>(E)) {
- return analyzeMemberExpr(ME);
- } else if (const DeclRefExpr *D = dyn_cast<const DeclRefExpr>(E)) {
- if (!hasMatchingVarInit(D))
- return VarInitMismatches;
- }
- return NoMismatch;
-}
-
-const CXXNewExpr *
-MismatchingNewDeleteDetector::getNewExprFromInitListOrExpr(const Expr *E) {
- assert(E != nullptr && "Expected a valid initializer expression");
- E = E->IgnoreParenImpCasts();
- if (const InitListExpr *ILE = dyn_cast<const InitListExpr>(E)) {
- if (ILE->getNumInits() == 1)
- E = dyn_cast<const CXXNewExpr>(ILE->getInit(0)->IgnoreParenImpCasts());
- }
-
- return dyn_cast<const CXXNewExpr>(E);
-}
-
-bool MismatchingNewDeleteDetector::hasMatchingNewInCtorInit(
- const CXXCtorInitializer *CI) {
- const CXXNewExpr *NE = nullptr;
- if (Field == CI->getMember() &&
- (NE = getNewExprFromInitListOrExpr(CI->getInit()))) {
- if (NE->isArray() == IsArrayForm)
- return true;
- else
- NewExprs.push_back(NE);
- }
- return false;
-}
-
-bool MismatchingNewDeleteDetector::hasMatchingNewInCtor(
- const CXXConstructorDecl *CD) {
- if (CD->isImplicit())
- return false;
- const FunctionDecl *Definition = CD;
- if (!CD->isThisDeclarationADefinition() && !CD->isDefined(Definition)) {
- HasUndefinedConstructors = true;
- return EndOfTU;
- }
- for (const auto *CI : cast<const CXXConstructorDecl>(Definition)->inits()) {
- if (hasMatchingNewInCtorInit(CI))
- return true;
- }
- return false;
-}
-
-MismatchingNewDeleteDetector::MismatchResult
-MismatchingNewDeleteDetector::analyzeInClassInitializer() {
- assert(Field != nullptr && "This should be called only for members");
- if (const CXXNewExpr *NE =
- getNewExprFromInitListOrExpr(Field->getInClassInitializer())) {
- if (NE->isArray() != IsArrayForm) {
- NewExprs.push_back(NE);
- return MemberInitMismatches;
- }
- }
- return NoMismatch;
-}
-
-MismatchingNewDeleteDetector::MismatchResult
-MismatchingNewDeleteDetector::analyzeField(FieldDecl *Field,
- bool DeleteWasArrayForm) {
- assert(Field != nullptr && "Analysis requires a valid class member.");
- this->Field = Field;
- IsArrayForm = DeleteWasArrayForm;
- const CXXRecordDecl *RD = cast<const CXXRecordDecl>(Field->getParent());
- for (const auto *CD : RD->ctors()) {
- if (hasMatchingNewInCtor(CD))
- return NoMismatch;
- }
- if (HasUndefinedConstructors)
- return EndOfTU ? NoMismatch : AnalyzeLater;
- if (!NewExprs.empty())
- return MemberInitMismatches;
- return Field->hasInClassInitializer() ? analyzeInClassInitializer()
- : NoMismatch;
-}
-
-MismatchingNewDeleteDetector::MismatchResult
-MismatchingNewDeleteDetector::analyzeMemberExpr(const MemberExpr *ME) {
- assert(ME != nullptr && "Expected a member expression");
- if (FieldDecl *F = dyn_cast<FieldDecl>(ME->getMemberDecl()))
- return analyzeField(F, IsArrayForm);
- return NoMismatch;
-}
-
-bool MismatchingNewDeleteDetector::hasMatchingVarInit(const DeclRefExpr *D) {
- const CXXNewExpr *NE = nullptr;
- if (const VarDecl *VD = dyn_cast<const VarDecl>(D->getDecl())) {
- if (VD->hasInit() && (NE = getNewExprFromInitListOrExpr(VD->getInit())) &&
- NE->isArray() != IsArrayForm) {
- NewExprs.push_back(NE);
- }
- }
- return NewExprs.empty();
-}
-
-static void
-DiagnoseMismatchedNewDelete(Sema &SemaRef, SourceLocation DeleteLoc,
- const MismatchingNewDeleteDetector &Detector) {
- SourceLocation EndOfDelete = SemaRef.getLocForEndOfToken(DeleteLoc);
- FixItHint H;
- if (!Detector.IsArrayForm)
- H = FixItHint::CreateInsertion(EndOfDelete, "[]");
- else {
- SourceLocation RSquare = Lexer::findLocationAfterToken(
- DeleteLoc, tok::l_square, SemaRef.getSourceManager(),
- SemaRef.getLangOpts(), true);
- if (RSquare.isValid())
- H = FixItHint::CreateRemoval(SourceRange(EndOfDelete, RSquare));
- }
- SemaRef.Diag(DeleteLoc, diag::warn_mismatched_delete_new)
- << Detector.IsArrayForm << H;
-
- for (const auto *NE : Detector.NewExprs)
- SemaRef.Diag(NE->getExprLoc(), diag::note_allocated_here)
- << Detector.IsArrayForm;
-}
-
-void Sema::AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE) {
- if (Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation()))
- return;
- MismatchingNewDeleteDetector Detector(/*EndOfTU=*/false);
- switch (Detector.analyzeDeleteExpr(DE)) {
- case MismatchingNewDeleteDetector::VarInitMismatches:
- case MismatchingNewDeleteDetector::MemberInitMismatches: {
- DiagnoseMismatchedNewDelete(*this, DE->getLocStart(), Detector);
- break;
- }
- case MismatchingNewDeleteDetector::AnalyzeLater: {
- DeleteExprs[Detector.Field].push_back(
- std::make_pair(DE->getLocStart(), DE->isArrayForm()));
- break;
- }
- case MismatchingNewDeleteDetector::NoMismatch:
- break;
- }
-}
-
-void Sema::AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,
- bool DeleteWasArrayForm) {
- MismatchingNewDeleteDetector Detector(/*EndOfTU=*/true);
- switch (Detector.analyzeField(Field, DeleteWasArrayForm)) {
- case MismatchingNewDeleteDetector::VarInitMismatches:
- llvm_unreachable("This analysis should have been done for class members.");
- case MismatchingNewDeleteDetector::AnalyzeLater:
- llvm_unreachable("Analysis cannot be postponed any point beyond end of "
- "translation unit.");
- case MismatchingNewDeleteDetector::MemberInitMismatches:
- DiagnoseMismatchedNewDelete(*this, DeleteLoc, Detector);
- break;
- case MismatchingNewDeleteDetector::NoMismatch:
- break;
- }
-}
-
/// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
/// @code ::delete ptr; @endcode
/// or
@@ -2709,6 +2454,12 @@ Sema::ActOnCXXDelete(SourceLocation Star
}
}
+ // C++ [expr.delete]p2:
+ // [Note: a pointer to a const type can be the operand of a
+ // delete-expression; it is not necessary to cast away the constness
+ // (5.2.11) of the pointer expression before it is used as the operand
+ // of the delete-expression. ]
+
if (Pointee->isArrayType() && !ArrayForm) {
Diag(StartLoc, diag::warn_delete_array_type)
<< Type << Ex.get()->getSourceRange()
@@ -2783,7 +2534,7 @@ Sema::ActOnCXXDelete(SourceLocation Star
DeleteName);
MarkFunctionReferenced(StartLoc, OperatorDelete);
-
+
// Check access and ambiguity of operator delete and destructor.
if (PointeeRD) {
if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
@@ -2793,11 +2544,9 @@ Sema::ActOnCXXDelete(SourceLocation Star
}
}
- CXXDeleteExpr *Result = new (Context) CXXDeleteExpr(
+ return new (Context) CXXDeleteExpr(
Context.VoidTy, UseGlobal, ArrayForm, ArrayFormAsWritten,
UsualArrayDeleteWantsSize, OperatorDelete, Ex.get(), StartLoc);
- AnalyzeDeleteExprMismatch(Result);
- return Result;
}
/// \brief Check the use of the given variable as a C++ condition in an if,
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu May 14 15:57:48 2015
@@ -3021,18 +3021,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, u
ReadSourceLocation(F, Record, I).getRawEncoding());
}
break;
- case DELETE_EXPRS_TO_ANALYZE:
- for (unsigned I = 0, N = Record.size(); I != N;) {
- DelayedDeleteExprs.push_back(getGlobalDeclID(F, Record[I++]));
- const uint64_t Count = Record[I++];
- DelayedDeleteExprs.push_back(Count);
- for (uint64_t C = 0; C < Count; ++C) {
- DelayedDeleteExprs.push_back(ReadSourceLocation(F, Record, I).getRawEncoding());
- bool IsArrayForm = Record[I++] == 1;
- DelayedDeleteExprs.push_back(IsArrayForm);
- }
- }
- break;
case IMPORTED_MODULES: {
if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule) {
@@ -7025,21 +7013,6 @@ void ASTReader::ReadUndefinedButUsed(
}
}
-void ASTReader::ReadMismatchingDeleteExpressions(llvm::MapVector<
- FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
- Exprs) {
- for (unsigned Idx = 0, N = DelayedDeleteExprs.size(); Idx != N;) {
- FieldDecl *FD = cast<FieldDecl>(GetDecl(DelayedDeleteExprs[Idx++]));
- uint64_t Count = DelayedDeleteExprs[Idx++];
- for (uint64_t C = 0; C < Count; ++C) {
- SourceLocation DeleteLoc =
- SourceLocation::getFromRawEncoding(DelayedDeleteExprs[Idx++]);
- const bool IsArrayForm = DelayedDeleteExprs[Idx++];
- Exprs[FD].push_back(std::make_pair(DeleteLoc, IsArrayForm));
- }
- }
-}
-
void ASTReader::ReadTentativeDefinitions(
SmallVectorImpl<VarDecl *> &TentativeDefs) {
for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu May 14 15:57:48 2015
@@ -4155,20 +4155,6 @@ void ASTWriter::WriteASTCore(Sema &SemaR
AddSourceLocation(I->second, UndefinedButUsed);
}
- // Build a record containing all delete-expressions that we would like to
- // analyze later in AST.
- RecordData DeleteExprsToAnalyze;
-
- for (const auto &DeleteExprsInfo :
- SemaRef.getMismatchingDeleteExpressions()) {
- AddDeclRef(DeleteExprsInfo.first, DeleteExprsToAnalyze);
- DeleteExprsToAnalyze.push_back(DeleteExprsInfo.second.size());
- for (const auto &DeleteLoc : DeleteExprsInfo.second) {
- AddSourceLocation(DeleteLoc.first, DeleteExprsToAnalyze);
- DeleteExprsToAnalyze.push_back(DeleteLoc.second);
- }
- }
-
// Write the control block
WriteControlBlock(PP, Context, isysroot, OutputFile);
@@ -4438,10 +4424,7 @@ void ASTWriter::WriteASTCore(Sema &SemaR
// Write the undefined internal functions and variables, and inline functions.
if (!UndefinedButUsed.empty())
Stream.EmitRecord(UNDEFINED_BUT_USED, UndefinedButUsed);
-
- if (!DeleteExprsToAnalyze.empty())
- Stream.EmitRecord(DELETE_EXPRS_TO_ANALYZE, DeleteExprsToAnalyze);
-
+
// Write the visible updates to DeclContexts.
for (auto *DC : UpdatedDeclContexts)
WriteDeclContextVisibleUpdate(DC);
Modified: cfe/trunk/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Malloc%2BMismatchedDeallocator%2BNewDelete.cpp?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp (original)
+++ cfe/trunk/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp Thu May 14 15:57:48 2015
@@ -97,11 +97,9 @@ void testShouldReportDoubleFreeNotMismat
free(p);
delete globalPtr; // expected-warning {{Attempt to free released memory}}
}
-int *allocIntArray(unsigned c) {
- return new int[c];
-}
+
void testMismatchedChangePointeeThroughAssignment() {
- int *arr = allocIntArray(4);
+ int *arr = new int[4];
globalPtr = arr;
delete arr; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
-}
+}
\ No newline at end of file
Modified: cfe/trunk/test/Analysis/MismatchedDeallocator-checker-test.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/MismatchedDeallocator-checker-test.mm?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/MismatchedDeallocator-checker-test.mm (original)
+++ cfe/trunk/test/Analysis/MismatchedDeallocator-checker-test.mm Thu May 14 15:57:48 2015
@@ -95,11 +95,8 @@ void testNew6() {
realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
}
-int *allocInt() {
- return new int;
-}
void testNew7() {
- int *p = allocInt();
+ int *p = new int;
delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}}
}
@@ -108,12 +105,8 @@ void testNew8() {
delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
}
-int *allocIntArray(unsigned c) {
- return new int[c];
-}
-
void testNew9() {
- int *p = allocIntArray(1);
+ int *p = new int[1];
delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
}
Modified: cfe/trunk/test/Analysis/MismatchedDeallocator-path-notes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/MismatchedDeallocator-path-notes.cpp?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/MismatchedDeallocator-path-notes.cpp (original)
+++ cfe/trunk/test/Analysis/MismatchedDeallocator-path-notes.cpp Thu May 14 15:57:48 2015
@@ -3,12 +3,9 @@
// RUN: FileCheck --input-file=%t.plist %s
void changePointee(int *p);
-int *allocIntArray(unsigned c) {
- return new int[c]; // expected-note {{Memory is allocated}}
-}
void test() {
- int *p = allocIntArray(1); // expected-note {{Calling 'allocIntArray'}}
- // expected-note at -1 {{Returned allocated memory}}
+ int *p = new int[1];
+ // expected-note at -1 {{Memory is allocated}}
changePointee(p);
delete p; // expected-warning {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
// expected-note at -1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
@@ -27,124 +24,13 @@ void test() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>24</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>27</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Calling 'allocIntArray'</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Calling 'allocIntArray'</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>1</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Entered call from 'test'</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Entered call from 'test'</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>1</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>6</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>7</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>7</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -152,12 +38,12 @@ void test() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -169,7 +55,7 @@ void test() {
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
@@ -177,52 +63,23 @@ void test() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
-// CHECK-NEXT: <key>col</key><integer>19</integer>
+// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Memory is allocated</string>
// CHECK-NEXT: <key>message</key>
// CHECK-NEXT: <string>Memory is allocated</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>27</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Returned allocated memory</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Returned allocated memory</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
// CHECK-NEXT: <key>edges</key>
// CHECK-NEXT: <array>
@@ -230,25 +87,25 @@ void test() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>line</key><integer>7</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>13</integer>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>13</integer>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -260,7 +117,7 @@ void test() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>13</integer>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -268,12 +125,12 @@ void test() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>13</integer>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>13</integer>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -295,7 +152,7 @@ void test() {
// CHECK-NEXT: <key>issue_hash</key><string>4</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>13</integer>
+// CHECK-NEXT: <key>line</key><integer>10</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
Modified: cfe/trunk/test/CodeGenCXX/new.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/new.cpp?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/new.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/new.cpp Thu May 14 15:57:48 2015
@@ -321,14 +321,14 @@ namespace N3664 {
// CHECK-LABEL: define void @_ZN5N36641fEv
void f() {
// CHECK: call noalias i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
- int *p = new int; // expected-note {{allocated with 'new' here}}
+ int *p = new int;
// CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]]
delete p;
// CHECK: call noalias i8* @_Znam(i64 12) [[ATTR_BUILTIN_NEW]]
int *q = new int[3];
// CHECK: call void @_ZdaPv({{.*}}) [[ATTR_BUILTIN_DELETE]]
- delete[] p; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
+ delete [] p;
// CHECK: call i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_BUILTIN_NOTHROW_NEW:#[^ ]*]]
(void) new (nothrow) S[3];
Removed: cfe/trunk/test/SemaCXX/delete-mismatch.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/delete-mismatch.h?rev=237390&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/delete-mismatch.h (original)
+++ cfe/trunk/test/SemaCXX/delete-mismatch.h (removed)
@@ -1,15 +0,0 @@
-// Header for PCH test delete.cpp
-namespace pch_test {
-struct X {
- int *a;
- X();
- X(int);
- X(bool)
- : a(new int[1]) { } // expected-note{{allocated with 'new[]' here}}
- ~X()
- {
- delete a; // expected-warning{{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]"
- }
-};
-}
Modified: cfe/trunk/test/SemaCXX/delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/delete.cpp?rev=237391&r1=237390&r2=237391&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/delete.cpp (original)
+++ cfe/trunk/test/SemaCXX/delete.cpp Thu May 14 15:57:48 2015
@@ -1,129 +1,9 @@
-// Test without PCH
-// RUN: %clang_cc1 -fsyntax-only -include %S/delete-mismatch.h -fdiagnostics-parseable-fixits -std=c++11 %s 2>&1 | FileCheck %s
-
-// Test with PCH
-// RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -o %t %S/delete-mismatch.h
-// RUN: %clang_cc1 -std=c++11 -include-pch %t -DWITH_PCH -fsyntax-only -verify %s -ast-dump
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: %clang_cc1 -fixit -x c++ %t
+// RUN: %clang_cc1 -E -o - %t | FileCheck %s
void f(int a[10][20]) {
+ // CHECK: delete[] a;
delete a; // expected-warning {{'delete' applied to a pointer-to-array type}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]"
-}
-namespace MemberCheck {
-struct S {
- int *a = new int[5]; // expected-note4 {{allocated with 'new[]' here}}
- int *b;
- int *c;
- static int *d;
- S();
- S(int);
- ~S() {
- delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
- delete b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
- delete[] c; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
- }
- void f();
-};
-
-void S::f()
-{
- delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
- delete b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
-}
-
-S::S()
-: b(new int[1]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}}
-// expected-note at -1 {{allocated with 'new' here}}
-
-S::S(int i)
-: b(new int[i]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}}
-// expected-note at -1 {{allocated with 'new' here}}
-
-struct S2 : S {
- ~S2() {
- delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
- }
-};
-int *S::d = new int[42]; // expected-note {{allocated with 'new[]' here}}
-void f(S *s) {
- int *a = new int[1]; // expected-note {{allocated with 'new[]' here}}
- delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
- delete s->a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
- delete s->b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
- delete s->c;
- delete s->d;
- delete S::d; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
-}
-
-// At least one constructor initializes field with matching form of 'new'.
-struct MatchingNewIsOK {
- int *p;
- bool is_array_;
- MatchingNewIsOK() : p{new int}, is_array_(false) {}
- explicit MatchingNewIsOK(unsigned c) : p{new int[c]}, is_array_(true) {}
- ~MatchingNewIsOK() {
- if (is_array_)
- delete[] p;
- else
- delete p;
- }
-};
-
-// At least one constructor's body is missing; no proof of mismatch.
-struct CantProve_MissingCtorDefinition {
- int *p;
- CantProve_MissingCtorDefinition();
- CantProve_MissingCtorDefinition(int);
- ~CantProve_MissingCtorDefinition();
-};
-
-CantProve_MissingCtorDefinition::CantProve_MissingCtorDefinition()
- : p(new int)
-{ }
-
-CantProve_MissingCtorDefinition::~CantProve_MissingCtorDefinition()
-{
- delete[] p;
-}
-
-struct base {};
-struct derived : base {};
-struct InitList {
- base *p;
- InitList() : p{new derived[1]} {} // expected-note {{allocated with 'new[]' here}}
- explicit InitList(unsigned c) : p(new derived[c]) {} // expected-note {{allocated with 'new[]' here}}
- InitList(unsigned c, unsigned) : p{new derived[c]} {} // expected-note {{allocated with 'new[]' here}}
- InitList(const char *) : p{new derived[1]} {} // expected-note {{allocated with 'new[]' here}}
- ~InitList() {
- delete p; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
- delete [] p;
- }
-};
-}
-
-namespace NonMemberCheck {
-#define DELETE_ARRAY(x) delete[] (x)
-#define DELETE(x) delete (x)
-void f() {
- int *a = new int(5); // expected-note2 {{allocated with 'new' here}}
- delete[] a; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
- int *b = new int;
- delete b;
- int *c{new int}; // expected-note {{allocated with 'new' here}}
- int *d{new int[1]}; // expected-note2 {{allocated with 'new[]' here}}
- delete [ ] c; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:17}:""
- delete d; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]"
- DELETE_ARRAY(a); // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
- DELETE(d); // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
-}
}
-#ifndef WITH_PCH
-pch_test::X::X()
- : a(new int[1]) // expected-note{{allocated with 'new[]' here}}
-{ }
-pch_test::X::X(int i)
- : a(new int[i]) // expected-note{{allocated with 'new[]' here}}
-{ }
-#endif
More information about the cfe-commits
mailing list