summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-07-17 17:46:44 +0000
committerJordan Rose <jordan_rose@apple.com>2012-07-17 17:46:44 +0000
commitea70bf71547b9c8d96735707541e55fe117e23b5 (patch)
tree4d5f161cadc8ae02a1bf04949bcf4750727d3cc3
parent7660f78fb95b3e1706019dce7cd4e845f262c018 (diff)
downloadbcm5719-llvm-ea70bf71547b9c8d96735707541e55fe117e23b5.tar.gz
bcm5719-llvm-ea70bf71547b9c8d96735707541e55fe117e23b5.zip
Add -Wobjc-string-compare under -Wobjc-literal-compare.
Suggested by Ted, since string literal comparison is at least slightly more sensible than comparison of runtime literals. (Ambiguous language on developer.apple.com implies that strings are guaranteed to be uniqued within a translation unit and possibly across a linked binary.) llvm-svn: 160378
-rw-r--r--clang/include/clang/Basic/DiagnosticGroups.td5
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td14
-rw-r--r--clang/lib/Sema/SemaExpr.cpp31
-rw-r--r--clang/test/SemaObjC/objc-literal-comparison.m18
4 files changed, 53 insertions, 15 deletions
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 1cce51ee311..10affb07d31 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -436,3 +436,8 @@ def ObjCRedundantAPIUse : DiagGroup<"objc-redundant-api-use", [
def ObjCCocoaAPI : DiagGroup<"objc-cocoa-api", [
ObjCRedundantAPIUse
]>;
+
+def ObjCStringComparison : DiagGroup<"objc-string-compare">;
+def ObjCLiteralComparison : DiagGroup<"objc-literal-compare", [
+ ObjCStringComparison
+ ]>;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e5eea9d48a1..0c5c01a6e18 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1611,19 +1611,23 @@ def err_box_literal_collection : Error<
"%select{string|character|boolean|numeric}0 literal must be prefixed by '@' "
"in a collection">;
def warn_objc_literal_comparison : Warning<
- "direct comparison of %select{a string literal|an array literal|"
- "a dictionary literal|a numeric literal|a boxed expression|}0 has "
- "undefined behavior">, InGroup<DiagGroup<"objc-literal-compare">>;
+ "direct comparison of %select{an array literal|a dictionary literal|"
+ "a numeric literal|a boxed expression|}0 has undefined behavior">,
+ InGroup<ObjCLiteralComparison>;
+def warn_objc_string_literal_comparison : Warning<
+ "direct comparison of a string literal has undefined behavior">,
+ InGroup<ObjCStringComparison>;
def note_objc_literal_comparison_isequal : Note<
"use 'isEqual:' instead">;
-def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", "
- "\"local-dynamic\", \"initial-exec\" or \"local-exec\"">;
let CategoryName = "Cocoa API Issue" in {
def warn_objc_redundant_literal_use : Warning<
"using %0 with a literal is redundant">, InGroup<ObjCRedundantLiteralUse>;
}
+def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", "
+ "\"local-dynamic\", \"initial-exec\" or \"local-exec\"">;
+
def err_only_annotate_after_access_spec : Error<
"access specifier can only have annotation attributes">;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 0548cccd1fe..fabd673d1b1 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6744,19 +6744,28 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc,
BinaryOperator::Opcode Opc){
Expr *Literal = (isObjCObjectLiteral(LHS) ? LHS : RHS).get();
- unsigned LiteralKind;
+ // This should be kept in sync with warn_objc_literal_comparison.
+ // LK_String should always be last, since it has its own flag.
+ enum {
+ LK_Array,
+ LK_Dictionary,
+ LK_Numeric,
+ LK_Boxed,
+ LK_String
+ } LiteralKind;
+
switch (Literal->getStmtClass()) {
case Stmt::ObjCStringLiteralClass:
// "string literal"
- LiteralKind = 0;
+ LiteralKind = LK_String;
break;
case Stmt::ObjCArrayLiteralClass:
// "array literal"
- LiteralKind = 1;
+ LiteralKind = LK_Array;
break;
case Stmt::ObjCDictionaryLiteralClass:
// "dictionary literal"
- LiteralKind = 2;
+ LiteralKind = LK_Dictionary;
break;
case Stmt::ObjCBoxedExprClass: {
Expr *Inner = cast<ObjCBoxedExpr>(Literal)->getSubExpr();
@@ -6767,20 +6776,20 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc,
case Stmt::ObjCBoolLiteralExprClass:
case Stmt::CXXBoolLiteralExprClass:
// "numeric literal"
- LiteralKind = 3;
+ LiteralKind = LK_Numeric;
break;
case Stmt::ImplicitCastExprClass: {
CastKind CK = cast<CastExpr>(Inner)->getCastKind();
// Boolean literals can be represented by implicit casts.
if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast) {
- LiteralKind = 3;
+ LiteralKind = LK_Numeric;
break;
}
// FALLTHROUGH
}
default:
// "boxed expression"
- LiteralKind = 4;
+ LiteralKind = LK_Boxed;
break;
}
break;
@@ -6789,8 +6798,12 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc,
llvm_unreachable("Unknown Objective-C object literal kind");
}
- S.Diag(Loc, diag::warn_objc_literal_comparison)
- << LiteralKind << Literal->getSourceRange();
+ if (LiteralKind == LK_String)
+ S.Diag(Loc, diag::warn_objc_string_literal_comparison)
+ << Literal->getSourceRange();
+ else
+ S.Diag(Loc, diag::warn_objc_literal_comparison)
+ << LiteralKind << Literal->getSourceRange();
if (BinaryOperator::isEqualityOp(Opc) &&
hasIsEqualMethod(S, LHS.get(), RHS.get())) {
diff --git a/clang/test/SemaObjC/objc-literal-comparison.m b/clang/test/SemaObjC/objc-literal-comparison.m
index b0ca139961a..ea42a176ef0 100644
--- a/clang/test/SemaObjC/objc-literal-comparison.m
+++ b/clang/test/SemaObjC/objc-literal-comparison.m
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare -verify %s
+
+// (test the warning flag as well)
typedef unsigned char BOOL;
@@ -63,3 +65,17 @@ void testComparisonsWithoutFixits() {
if (@"" >= @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}}
}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wobjc-string-compare"
+
+void testWarningFlags(id obj) {
+ if (obj == @"") return; // no-warning
+ if (@"" == obj) return; // no-warning
+
+ if (obj == @1) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}
+ if (@1 == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}
+}
+
+#pragma clang diagnostic pop
+
OpenPOWER on IntegriCloud