diff options
| -rw-r--r-- | clang/lib/Sema/Sema.cpp | 17 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 16 | ||||
| -rw-r--r-- | clang/test/Modules/new-delete.cpp | 23 | 
3 files changed, 39 insertions, 17 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 7a8cd1ca4e6..d6d105c3b04 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1010,11 +1010,6 @@ void Sema::ActOnEndOfTranslationUnit() {      // Warnings emitted in ActOnEndOfTranslationUnit() should be emitted for      // modules when they are built, not every time they are used.      emitAndClearUnusedLocalTypedefWarnings(); - -    // Modules don't need any of the checking below. -    if (!PP.isIncrementalProcessingEnabled()) -      TUScope = nullptr; -    return;    }    // C99 6.9.2p2: @@ -1032,8 +1027,7 @@ void Sema::ActOnEndOfTranslationUnit() {    for (TentativeDefinitionsType::iterator              T = TentativeDefinitions.begin(ExternalSource),           TEnd = TentativeDefinitions.end(); -       T != TEnd; ++T) -  { +       T != TEnd; ++T) {      VarDecl *VD = (*T)->getActingDefinition();      // If the tentative definition was completed, getActingDefinition() returns @@ -1060,12 +1054,13 @@ void Sema::ActOnEndOfTranslationUnit() {      // Notify the consumer that we've completed a tentative definition.      if (!VD->isInvalidDecl())        Consumer.CompleteTentativeDefinition(VD); -    }    // If there were errors, disable 'unused' warnings since they will mostly be -  // noise. -  if (!Diags.hasErrorOccurred()) { +  // noise. Don't warn for a use from a module: either we should warn on all +  // file-scope declarations in modules or not at all, but whether the +  // declaration is used is immaterial. +  if (!Diags.hasErrorOccurred() && TUKind != TU_Module) {      // Output warning for unused file scoped decls.      for (UnusedFileScopedDeclsType::iterator             I = UnusedFileScopedDecls.begin(ExternalSource), @@ -1133,6 +1128,8 @@ void Sema::ActOnEndOfTranslationUnit() {    }    if (!Diags.isIgnored(diag::warn_unused_private_field, SourceLocation())) { +    // FIXME: Load additional unused private field candidates from the external +    // source.      RecordCompleteMap RecordsComplete;      RecordCompleteMap MNCComplete;      for (NamedDeclSetType::iterator I = UnusedPrivateFields.begin(), diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 7d5b521d4d9..1c838ae2c0d 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -4769,13 +4769,15 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,    // 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); +  if (!isModule) { +    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); +      }      }    } diff --git a/clang/test/Modules/new-delete.cpp b/clang/test/Modules/new-delete.cpp new file mode 100644 index 00000000000..585a242b224 --- /dev/null +++ b/clang/test/Modules/new-delete.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fmodules -verify %s +// expected-no-diagnostics + +#pragma clang module build M +module M {} +#pragma clang module contents +#pragma clang module begin M +struct A { +  A(); +  ~A() { delete p; } // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'}} +  int *p; +}; +inline A::A() : p(new int[32]) {} // expected-note {{allocated}} +struct B { +  B(); +  ~B() { delete p; } +  int *p; +}; +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import M +B::B() : p(new int[32]) {}  | 

