[cfe-commits] [PATCH] Fix diagnostic reporting of previous default statement.

sashan sashan at zenskg.net
Sat Dec 4 02:53:13 PST 2010


Hi

This is related to this thread here:
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2010-November/012302.html

This patch fixes the incorrect error reporting where the wrong previous line was
identified as containing the duplicate 'default'. The patch also contains a test
case for this. All the other test cases pass. Applying with:

  patch -p1 < patchfile

from the clang root source dir should work.

Thanks


-------------- next part --------------
>From 2fc1506ef5e9f8448b4f26c7b33713fc125d8a66 Mon Sep 17 00:00:00 2001
From: sashan <sashan at zenskg.net>
Date: Sat, 4 Dec 2010 20:01:01 +1100
Subject: [PATCH] Fix diagnostic reporting of previous default statements.

The diagnostic reporting code that dealt with duplicate default statements
assumed that the first of the statments in the stack was the duplicate statement
and the second was the original statement. This isn't always true. For example,
in this case:

  default:
  default:;

the statements appeared in reverse order to the next example:

  default:;
  default:;

This is due to the way the rcd parser works. It would result in the incorrect
line being identified as the duplicate 'default'.  Anyway the fix is to change
the diagnostic code to check which 'default' appears before the other, ordered by
line number, and apply the correct diagnostic message to it.

Also added a test case for this under stmt.switch p3.
---
 lib/Sema/SemaStmt.cpp                             |   14 ++++++++++++--
 test/CXX/stmt.stmt/stmt.label/p1.cpp              |   10 ----------
 test/CXX/stmt.stmt/stmt.select/stmt.switch/p3.cpp |   21 +++++++++++++++++++++
 3 files changed, 33 insertions(+), 12 deletions(-)
 create mode 100644 test/CXX/stmt.stmt/stmt.select/stmt.switch/p3.cpp

diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 7ab30d1..5f07fd4 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -550,8 +550,18 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
 
     if (DefaultStmt *DS = dyn_cast<DefaultStmt>(SC)) {
       if (TheDefaultStmt) {
-        Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);
-        Diag(TheDefaultStmt->getDefaultLoc(), diag::note_duplicate_case_prev);
+        PresumedLoc DSPLoc = SourceMgr.getPresumedLoc(DS->getDefaultLoc());
+        PresumedLoc TheDSPLoc = SourceMgr.getPresumedLoc(TheDefaultStmt->getDefaultLoc());
+
+        // Check which of the default statements is the duplicate by comparing
+        // their line numbers.
+        if (TheDSPLoc.getLine() < DSPLoc.getLine()) {
+          Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);
+          Diag(TheDefaultStmt->getDefaultLoc(), diag::note_duplicate_case_prev);
+        } else {
+          Diag(TheDefaultStmt->getDefaultLoc(), diag::err_multiple_default_labels_defined);
+          Diag(DS->getDefaultLoc(), diag::note_duplicate_case_prev);
+        }
 
         // FIXME: Remove the default statement from the switch block so that
         // we'll return a valid AST.  This requires recursing down the AST and
diff --git a/test/CXX/stmt.stmt/stmt.label/p1.cpp b/test/CXX/stmt.stmt/stmt.label/p1.cpp
index f2ace35..c1e0250 100644
--- a/test/CXX/stmt.stmt/stmt.label/p1.cpp
+++ b/test/CXX/stmt.stmt/stmt.label/p1.cpp
@@ -13,13 +13,3 @@ label1: // expected-error{{redefinition of label ''label1''}}
   x = 2;
 }
 
-void h()
-{
-  int x = 0;
-  switch (x)
-  {
-    case 1:;
-    default:; // expected-error{{multiple default labels in one switch}}
-    default:; // expected-note{{previous case defined here}}
-  }
-}
diff --git a/test/CXX/stmt.stmt/stmt.select/stmt.switch/p3.cpp b/test/CXX/stmt.stmt/stmt.select/stmt.switch/p3.cpp
new file mode 100644
index 0000000..b117de9
--- /dev/null
+++ b/test/CXX/stmt.stmt/stmt.select/stmt.switch/p3.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+void h()
+{
+  int x = 0;
+  switch (x)
+  {
+    default:; // expected-note{{previous case defined here}}
+    default:; // expected-error{{multiple default labels in one switch}}
+  }
+}
+
+void f()
+{
+  int x = 0;
+  switch (x)
+  {
+    default: // expected-note{{previous case defined here}}
+    default:; // expected-error{{multiple default labels in one switch}}
+  }
+}
+
-- 
1.7.2.3



More information about the cfe-commits mailing list