[cfe-commits] r156904 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaStmt.cpp test/Sema/switch.c
Douglas Gregor
dgregor at apple.com
Tue May 15 22:32:58 PDT 2012
Author: dgregor
Date: Wed May 16 00:32:58 2012
New Revision: 156904
URL: http://llvm.org/viewvc/llvm-project?rev=156904&view=rev
Log:
Produce more useful 'duplicate case' diagnostics. Fixes PR9243, from Terry Long!
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/test/Sema/switch.c
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=156904&r1=156903&r2=156904&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed May 16 00:32:58 2012
@@ -5229,6 +5229,8 @@
"overflow converting case value to switch condition type (%0 to %1)">,
InGroup<DiagGroup<"switch">>;
def err_duplicate_case : Error<"duplicate case value '%0'">;
+def err_duplicate_case_differing_expr : Error<
+ "duplicate case value: '%0' and '%1' both equal '%2'">;
def warn_case_empty_range : Warning<"empty case range specified">;
def warn_missing_case_for_condition :
Warning<"no case matching constant switch condition '%0'">;
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=156904&r1=156903&r2=156904&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Wed May 16 00:32:58 2012
@@ -768,8 +768,29 @@
if (i != 0 && CaseVals[i].first == CaseVals[i-1].first) {
// If we have a duplicate, report it.
- Diag(CaseVals[i].second->getLHS()->getLocStart(),
- diag::err_duplicate_case) << CaseVals[i].first.toString(10);
+ // First, determine if either case value has a name
+ StringRef PrevString, CurrString;
+ Expr *PrevCase = CaseVals[i-1].second->getLHS()->IgnoreParenCasts();
+ Expr *CurrCase = CaseVals[i].second->getLHS()->IgnoreParenCasts();
+ if (DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(PrevCase)) {
+ PrevString = DeclRef->getDecl()->getName();
+ }
+ if (DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(CurrCase)) {
+ CurrString = DeclRef->getDecl()->getName();
+ }
+ std::string CaseValStr = CaseVals[i-1].first.toString(10);
+
+ if (PrevString == CurrString)
+ Diag(CaseVals[i].second->getLHS()->getLocStart(),
+ diag::err_duplicate_case) <<
+ (PrevString.empty() ? CaseValStr : PrevString.str());
+ else
+ Diag(CaseVals[i].second->getLHS()->getLocStart(),
+ diag::err_duplicate_case_differing_expr) <<
+ (PrevString.empty() ? CaseValStr : PrevString.str()) <<
+ (CurrString.empty() ? CaseValStr : CurrString.str()) <<
+ CaseValStr;
+
Diag(CaseVals[i-1].second->getLHS()->getLocStart(),
diag::note_duplicate_case_prev);
// FIXME: We really want to remove the bogus case stmt from the
Modified: cfe/trunk/test/Sema/switch.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/switch.c?rev=156904&r1=156903&r2=156904&view=diff
==============================================================================
--- cfe/trunk/test/Sema/switch.c (original)
+++ cfe/trunk/test/Sema/switch.c Wed May 16 00:32:58 2012
@@ -9,7 +9,7 @@
switch (X) {
case 42: ; // expected-note {{previous case}}
case 5000000000LL: // expected-warning {{overflow}}
- case 42: // expected-error {{duplicate case value}}
+ case 42: // expected-error {{duplicate case value '42'}}
;
case 100 ... 99: ; // expected-warning {{empty case range}}
@@ -320,3 +320,32 @@
break;
}
}
+
+// PR9243
+#define TEST19MACRO 5
+void test19(int i) {
+ enum {
+ kTest19Enum1 = 7,
+ kTest19Enum2 = 7
+ };
+ const int a = 3;
+ switch (i) {
+ case 5: // expected-note {{previous case}}
+ case TEST19MACRO: // expected-error {{duplicate case value '5'}}
+
+ case 7: // expected-note {{previous case}}
+ case kTest19Enum1: // expected-error {{duplicate case value: '7' and 'kTest19Enum1' both equal '7'}} \
+ // expected-note {{previous case}}
+ case kTest19Enum1: // expected-error {{duplicate case value 'kTest19Enum1'}} \
+ // expected-note {{previous case}}
+ case kTest19Enum2: // expected-error {{duplicate case value: 'kTest19Enum1' and 'kTest19Enum2' both equal '7'}} \
+ // expected-note {{previous case}}
+ case (int)kTest19Enum2: //expected-error {{duplicate case value 'kTest19Enum2'}}
+
+ case 3: // expected-note {{previous case}}
+ case a: // expected-error {{duplicate case value: '3' and 'a' both equal '3'}} \
+ // expected-note {{previous case}}
+ case a: // expected-error {{duplicate case value 'a'}}
+ break;
+ }
+}
More information about the cfe-commits
mailing list