[PATCH] D25113: [Sema] Don't display an invalid redefinition error when dealing with a redefinition of a function whose previous definition was typo-corrected

Alex Lorenz via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 30 11:35:57 PDT 2016


arphaman created this revision.
arphaman added a reviewer: rsmith.
arphaman added a subscriber: cfe-commits.
arphaman set the repository for this revision to rL LLVM.

This patch improves the displayed diagnostics when encountering a redefinition of a function whose previous definition was typo-corrected.

For example, given a code sample like this:

  class Foo {
    int* create_process(int pid, const char* name);
  };
  
  int *Foo::create_process2(int pid, const char* name) {
    return 0;
  }
  
  int *Foo::create_process(int pid, const char* name) {
    return 0;
  }

Clang will now show only the error diagnostic for the definition of create_process2: "out-of-line definition of 'create_process2' does not match any declaration in 'Foo'; did you mean 'create_process'?". However, prior to this patch, clang would have also shown a second error diagnostic for the definition of create_process: "redefinition of 'create_process'". The second diagnostic shouldn't be presented as it's not true, and the automatic renaming of create_process2 shouldn't cause such an error.


Repository:
  rL LLVM

https://reviews.llvm.org/D25113

Files:
  include/clang/Sema/Sema.h
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/typo-correction.cpp


Index: test/SemaCXX/typo-correction.cpp
===================================================================
--- test/SemaCXX/typo-correction.cpp
+++ test/SemaCXX/typo-correction.cpp
@@ -679,3 +679,33 @@
       sizeof(c0is0)]; // expected-error {{use of undeclared identifier}}
 };
 }
+
+namespace {
+class Foo {
+  int* create_process(int pid); // expected-note {{'create_process' declared here}}
+};
+
+int *Foo::create_process2(int pid) { // expected-error {{out-of-line definition of 'create_process2' does not match any declaration in '(anonymous namespace)::Foo'; did you mean 'create_process'?}}
+  return 0;
+}
+
+// Expected no redefinition error here.
+int *Foo::create_process(int pid) { // expected-note {{previous definition is here}}
+  return 0;
+}
+
+int *Foo::create_process(int pid) { // expected-error {{redefinition of 'create_process'}}
+  return 0;
+}
+
+namespace test {
+void create_test(); // expected-note {{'create_test' declared here}}
+}
+
+void test::create_test2() { // expected-error {{out-of-line definition of 'create_test2' does not match any declaration in namespace '(anonymous namespace)::test'; did you mean 'create_test'?}}
+}
+
+// Expected no redefinition error here.
+void test::create_test() {
+}
+}
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -7191,6 +7191,10 @@
 
 } // end anonymous namespace
 
+void Sema::MarkTypoCorrectedFunctionDefinition(const NamedDecl *F) {
+  TypoCorrectedFunctionDefinitions.insert(F);
+}
+
 /// \brief Generate diagnostics for an invalid function redeclaration.
 ///
 /// This routine handles generating the diagnostic messages for an invalid
@@ -7288,6 +7292,8 @@
         if ((*I)->getCanonicalDecl() == Canonical)
           Correction.setCorrectionDecl(*I);
 
+      // Let Sema know about the correction.
+      SemaRef.MarkTypoCorrectedFunctionDefinition(Result);
       SemaRef.diagnoseTypo(
           Correction,
           SemaRef.PDiag(IsLocalFriend
@@ -11315,6 +11321,11 @@
   if (canRedefineFunction(Definition, getLangOpts()))
     return;
 
+  // Don't emit an error when this is redifinition of a typo-corrected
+  // definition.
+  if (TypoCorrectedFunctionDefinitions.count(Definition))
+    return;
+
   // If we don't have a visible definition of the function, and it's inline or
   // a template, skip the new definition.
   if (SkipBody && !hasVisibleDefinition(Definition) &&
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -1031,6 +1031,12 @@
   /// currently being copy-initialized. Can be empty.
   llvm::SmallVector<QualType, 4> CurrentParameterCopyTypes;
 
+  /// The function definitions which were renamed as part of typo-correction
+  /// to match their respective declarations. We want to keep track of them
+  /// to ensure that we don't emit a "redefinition" error if we encounter a
+  /// correctly named definition after the renamed definition.
+  llvm::SmallPtrSet<const NamedDecl *, 4> TypoCorrectedFunctionDefinitions;
+
   void ReadMethodPool(Selector Sel);
   void updateOutOfDateSelector(Selector Sel);
 
@@ -3012,6 +3018,8 @@
                     const PartialDiagnostic &PrevNote,
                     bool ErrorRecovery = true);
 
+  void MarkTypoCorrectedFunctionDefinition(const NamedDecl *F);
+
   void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc,
                                           ArrayRef<Expr *> Args,
                                    AssociatedNamespaceSet &AssociatedNamespaces,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25113.73103.patch
Type: text/x-patch
Size: 3664 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160930/6b5aa1c1/attachment.bin>


More information about the cfe-commits mailing list