Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Mar 28, 2020. It is now read-only.
/swift-clangPublic archive

Commitd5e7441

Browse files
committed
[Sema] Split of versions of -Wimplicit-{float,int}-conversion for Objective-C BOOL
Also, add a diagnostic group, -Wobjc-signed-char-bool, to control all theserelated diagnostics.rdar://51954400Differential revision:https://reviews.llvm.org/D67559git-svn-id:https://llvm.org/svn/llvm-project/cfe/trunk@372183 91177308-0d34-0410-b5e6-96231b3b80d8Conflicts:include/clang/Basic/DiagnosticGroups.tdlib/Sema/SemaChecking.cpp
1 parent3520198 commitd5e7441

File tree

6 files changed

+161
-35
lines changed

6 files changed

+161
-35
lines changed

‎include/clang/Basic/DiagnosticGroups.td‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,16 @@ def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion,
6161
UndefinedBoolConversion]>;
6262
def IntConversion : DiagGroup<"int-conversion">;
6363
def EnumConversion : DiagGroup<"enum-conversion">;
64-
def ImplicitIntConversion : DiagGroup<"implicit-int-conversion">;
65-
def ImplicitFloatConversion : DiagGroup<"implicit-float-conversion">;
64+
def ObjCSignedCharBoolImplicitIntConversion :
65+
DiagGroup<"objc-signed-char-bool-implicit-int-conversion">;
66+
def ImplicitIntConversion : DiagGroup<"implicit-int-conversion",
67+
[ObjCSignedCharBoolImplicitIntConversion]>;
68+
def ImplicitIntFloatConversion : DiagGroup<"implicit-int-float-conversion">;
69+
def ObjCSignedCharBoolImplicitFloatConversion :
70+
DiagGroup<"objc-signed-char-bool-implicit-float-conversion">;
71+
def ImplicitFloatConversion : DiagGroup<"implicit-float-conversion",
72+
[ImplicitIntFloatConversion,
73+
ObjCSignedCharBoolImplicitFloatConversion]>;
6674
def ImplicitFixedPointConversion : DiagGroup<"implicit-fixed-point-conversion">;
6775

6876
def FloatOverflowConversion : DiagGroup<"float-overflow-conversion">;
@@ -1000,6 +1008,12 @@ def ObjCLiteralComparison : DiagGroup<"objc-literal-compare", [
10001008
ObjCStringComparison
10011009
]>;
10021010

1011+
def ObjCSignedCharBool : DiagGroup<"objc-signed-char-bool",
1012+
[ObjCSignedCharBoolImplicitIntConversion,
1013+
ObjCSignedCharBoolImplicitFloatConversion,
1014+
ObjCBoolConstantConversion,
1015+
TautologicalObjCBoolCompare]>;
1016+
10031017
// Inline ASM warnings.
10041018
def ASMOperandWidths : DiagGroup<"asm-operand-widths">;
10051019
def ASMIgnoredQualifier : DiagGroup<"asm-ignored-qualifier">;

‎include/clang/Basic/DiagnosticSemaKinds.td‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3253,7 +3253,7 @@ def warn_impcast_integer_precision_constant : Warning<
32533253
def warn_impcast_bitfield_precision_constant : Warning<
32543254
"implicit truncation from %2 to bit-field changes value from %0 to %1">,
32553255
InGroup<BitFieldConstantConversion>;
3256-
defwarn_impcast_constant_int_to_objc_bool : Warning<
3256+
defwarn_impcast_constant_value_to_objc_bool : Warning<
32573257
"implicit conversion from constant value %0 to 'BOOL'; "
32583258
"the only well defined values for 'BOOL' are YES and NO">,
32593259
InGroup<ObjCBoolConstantConversion>;
@@ -3271,6 +3271,12 @@ def warn_impcast_literal_float_to_integer_out_of_range : Warning<
32713271
def warn_impcast_float_integer : Warning<
32723272
"implicit conversion turns floating-point number into integer: %0 to %1">,
32733273
InGroup<FloatConversion>, DefaultIgnore;
3274+
def warn_impcast_float_to_objc_signed_char_bool : Warning<
3275+
"implicit conversion from floating-point type %0 to 'BOOL'">,
3276+
InGroup<ObjCSignedCharBoolImplicitFloatConversion>;
3277+
def warn_impcast_int_to_objc_signed_char_bool : Warning<
3278+
"implicit conversion from integral type %0 to 'BOOL'">,
3279+
InGroup<ObjCSignedCharBoolImplicitIntConversion>, DefaultIgnore;
32743280

32753281
def warn_impcast_float_to_integer : Warning<
32763282
"implicit conversion from %0 to %1 changes value from %2 to %3">,

‎lib/AST/Expr.cpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ bool Expr::isKnownToHaveBooleanValue() const {
185185
return CO->getTrueExpr()->isKnownToHaveBooleanValue() &&
186186
CO->getFalseExpr()->isKnownToHaveBooleanValue();
187187

188+
if (isa<ObjCBoolLiteralExpr>(E))
189+
returntrue;
190+
191+
if (constauto *OVE = dyn_cast<OpaqueValueExpr>(E))
192+
return OVE->getSourceExpr()->isKnownToHaveBooleanValue();
193+
188194
returnfalse;
189195
}
190196

‎lib/Sema/SemaChecking.cpp‎

Lines changed: 63 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10801,6 +10801,26 @@ static void DiagnoseImpCast(Sema &S, Expr *E, QualType T,
1080110801
DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, pruneControlFlow);
1080210802
}
1080310803

10804+
static bool isObjCSignedCharBool(Sema &S, QualType Ty) {
10805+
return Ty->isSpecificBuiltinType(BuiltinType::SChar) &&
10806+
S.getLangOpts().ObjC && S.NSAPIObj->isObjCBOOLType(Ty);
10807+
}
10808+
10809+
static void adornObjCBoolConversionDiagWithTernaryFixit(
10810+
Sema &S, Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder) {
10811+
Expr *Ignored = SourceExpr->IgnoreImplicit();
10812+
if (const auto *OVE = dyn_cast<OpaqueValueExpr>(Ignored))
10813+
Ignored = OVE->getSourceExpr();
10814+
bool NeedsParens = isa<AbstractConditionalOperator>(Ignored) ||
10815+
isa<BinaryOperator>(Ignored) ||
10816+
isa<CXXOperatorCallExpr>(Ignored);
10817+
SourceLocation EndLoc = S.getLocForEndOfToken(SourceExpr->getEndLoc());
10818+
if (NeedsParens)
10819+
Builder << FixItHint::CreateInsertion(SourceExpr->getBeginLoc(), "(")
10820+
<< FixItHint::CreateInsertion(EndLoc, ")");
10821+
Builder << FixItHint::CreateInsertion(EndLoc, " ? YES : NO");
10822+
}
10823+
1080410824
/// Diagnose an implicit cast from a floating point value to an integer value.
1080510825
static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,
1080610826
SourceLocation CContext) {
@@ -10820,6 +10840,13 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,
1082010840
bool IsConstant =
1082110841
E->EvaluateAsFloat(Value, S.Context, Expr::SE_AllowSideEffects);
1082210842
if (!IsConstant) {
10843+
if (isObjCSignedCharBool(S, T)) {
10844+
return adornObjCBoolConversionDiagWithTernaryFixit(
10845+
S, E,
10846+
S.Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
10847+
<< E->getType());
10848+
}
10849+
1082310850
return DiagnoseImpCast(S, E, T, CContext,
1082410851
diag::warn_impcast_float_integer, PruneWarnings);
1082510852
}
@@ -10831,6 +10858,23 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,
1083110858
llvm::APFloat::opStatus Result = Value.convertToInteger(
1083210859
IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
1083310860

10861+
// FIXME: Force the precision of the source value down so we don't print
10862+
// digits which are usually useless (we don't really care here if we
10863+
// truncate a digit by accident in edge cases). Ideally, APFloat::toString
10864+
// would automatically print the shortest representation, but it's a bit
10865+
// tricky to implement.
10866+
SmallString<16> PrettySourceValue;
10867+
unsigned precision = llvm::APFloat::semanticsPrecision(Value.getSemantics());
10868+
precision = (precision * 59 + 195) / 196;
10869+
Value.toString(PrettySourceValue, precision);
10870+
10871+
if (isObjCSignedCharBool(S, T) && IntegerValue != 0 && IntegerValue != 1) {
10872+
return adornObjCBoolConversionDiagWithTernaryFixit(
10873+
S, E,
10874+
S.Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
10875+
<< PrettySourceValue);
10876+
}
10877+
1083410878
if (Result == llvm::APFloat::opOK && isExact) {
1083510879
if (IsLiteral) return;
1083610880
return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,
@@ -10874,16 +10918,6 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,
1087410918
DiagID = diag::warn_impcast_float_to_integer;
1087510919
}
1087610920

10877-
// FIXME: Force the precision of the source value down so we don't print
10878-
// digits which are usually useless (we don't really care here if we
10879-
// truncate a digit by accident in edge cases). Ideally, APFloat::toString
10880-
// would automatically print the shortest representation, but it's a bit
10881-
// tricky to implement.
10882-
SmallString<16> PrettySourceValue;
10883-
unsigned precision = llvm::APFloat::semanticsPrecision(Value.getSemantics());
10884-
precision = (precision * 59 + 195) / 196;
10885-
Value.toString(PrettySourceValue, precision);
10886-
1088710921
SmallString<16> PrettyTargetValue;
1088810922
if (IsBool)
1088910923
PrettyTargetValue = Value.isZero() ? "false" : "true";
@@ -11160,14 +11194,10 @@ static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T,
1116011194
return true;
1116111195
}
1116211196

11163-
static bool isObjCSignedCharBool(Sema &S, QualType Ty) {
11164-
return Ty->isSpecificBuiltinType(BuiltinType::SChar) &&
11165-
S.getLangOpts().ObjC && S.NSAPIObj->isObjCBOOLType(Ty);
11166-
}
11167-
11168-
static void
11169-
CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,
11170-
bool *ICContext = nullptr) {
11197+
static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
11198+
SourceLocation CC,
11199+
bool *ICContext = nullptr,
11200+
bool IsListInit = false) {
1117111201
if (E->isTypeDependent() || E->isValueDependent()) return;
1117211202

1117311203
const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr();
@@ -11214,19 +11244,13 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,
1121411244
if (isObjCSignedCharBool(S, T) && Source->isIntegralType(S.Context)) {
1121511245
Expr::EvalResult Result;
1121611246
if (E->EvaluateAsInt(Result, S.getASTContext(),
11217-
Expr::SE_AllowSideEffects) &&
11218-
Result.Val.getInt() != 1 && Result.Val.getInt() != 0) {
11219-
auto Builder = S.Diag(CC, diag::warn_impcast_constant_int_to_objc_bool)
11220-
<< Result.Val.getInt().toString(10);
11221-
Expr *Ignored = E->IgnoreImplicit();
11222-
bool NeedsParens = isa<AbstractConditionalOperator>(Ignored) ||
11223-
isa<BinaryOperator>(Ignored) ||
11224-
isa<CXXOperatorCallExpr>(Ignored);
11225-
SourceLocation EndLoc = S.getLocForEndOfToken(E->getEndLoc());
11226-
if (NeedsParens)
11227-
Builder << FixItHint::CreateInsertion(E->getBeginLoc(), "(")
11228-
<< FixItHint::CreateInsertion(EndLoc, ")");
11229-
Builder << FixItHint::CreateInsertion(EndLoc, " ? YES : NO");
11247+
Expr::SE_AllowSideEffects)) {
11248+
if (Result.Val.getInt() != 1 && Result.Val.getInt() != 0) {
11249+
adornObjCBoolConversionDiagWithTernaryFixit(
11250+
S, E,
11251+
S.Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
11252+
<< Result.Val.getInt().toString(10));
11253+
}
1123011254
return;
1123111255
}
1123211256
}
@@ -11421,6 +11445,14 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,
1142111445
if (Target->isSpecificBuiltinType(BuiltinType::Bool))
1142211446
return;
1142311447

11448+
if (isObjCSignedCharBool(S, T) && !Source->isCharType() &&
11449+
!E->isKnownToHaveBooleanValue()) {
11450+
return adornObjCBoolConversionDiagWithTernaryFixit(
11451+
S, E,
11452+
S.Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
11453+
<< E->getType());
11454+
}
11455+
1142411456
IntRange SourceRange = GetExprRange(S.Context, E, S.isConstantEvaluated());
1142511457
IntRange TargetRange = IntRange::forTargetOfCanonicalType(S.Context, Target);
1142611458

‎test/Sema/objc-bool-constant-conversion-fixit.m‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -Werror=constant-conversion %s -fixit-recompile -fixit-to-temporary -E -o - | FileCheck %s
1+
// RUN: %clang_cc1 -Werror=objc-signed-char-bool %s -fixit-recompile -fixit-to-temporary -E -o - | FileCheck %s
22

33
typedefsignedcharBOOL;
44

@@ -25,6 +25,17 @@ int main() {
2525

2626
b =1 <<1;
2727
// CHECK: b = (1 << 1) ? YES : NO;
28+
29+
int i;
30+
31+
b = i;
32+
// CHECK: b = i ? YES : NO;
33+
34+
b = i *2;
35+
// CHECK b = (i * 2) ? YES : NO;
36+
37+
b =1 ?2 :3;
38+
// CHECK: b = 1 ? 2 ? YES : NO : 3 ? YES : NO;
2839
}
2940

3041
@interfaceBoolProp
@@ -37,4 +48,12 @@ void f(BoolProp *bp) {
3748

3849
[bpsetB:43];
3950
// CHECK: [bp setB:43 ? YES : NO];
51+
52+
int i;
53+
54+
bp.b = i;
55+
// CHECK: bp.b = i ? YES : NO;
56+
57+
bp.b = i +1;
58+
// CHECK: bp.b = (i + 1) ? YES : NO;
4059
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: %clang_cc1 %s -verify -Wobjc-signed-char-bool
2+
// RUN: %clang_cc1 -xobjective-c++ %s -verify -Wobjc-signed-char-bool
3+
4+
typedefsignedcharBOOL;
5+
#defineYES __objc_yes
6+
#defineNO __objc_no
7+
8+
typedefunsignedchar Boolean;
9+
10+
BOOL b;
11+
Boolean boolean;
12+
float fl;
13+
int i;
14+
int *ptr;
15+
16+
voidt1() {
17+
b = boolean;
18+
b = fl;// expected-warning {{implicit conversion from floating-point type 'float' to 'BOOL'}}
19+
b = i;// expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}}
20+
21+
b =1.0;
22+
b =0.0;
23+
b =1.1;// expected-warning {{implicit conversion from 'double' to 'BOOL' (aka 'signed char') changes value from 1.1 to 1}}
24+
b =2.1;// expected-warning {{implicit conversion from constant value 2.1 to 'BOOL'; the only well defined values for 'BOOL' are YES and NO}}
25+
26+
b =YES;
27+
#ifndef __cplusplus
28+
b = ptr;// expected-warning {{incompatible pointer to integer conversion assigning to 'BOOL' (aka 'signed char') from 'int *'}}
29+
#endif
30+
}
31+
32+
@interfaceBoolProp
33+
@propertyBOOL p;
34+
@end
35+
36+
voidt2(BoolProp *bp) {
37+
bp.p =YES;
38+
bp.p =NO;
39+
bp.p = boolean;
40+
bp.p = fl;// expected-warning {{implicit conversion from floating-point type 'float' to 'BOOL'}}
41+
bp.p = i;// expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}}
42+
bp.p = b;
43+
bp.p = bp.p;
44+
#ifndef __cplusplus
45+
bp.p = ptr;// expected-warning {{incompatible pointer to integer conversion assigning to 'BOOL' (aka 'signed char') from 'int *'}}
46+
#endif
47+
bp.p =1;
48+
bp.p =2;// expected-warning {{implicit conversion from constant value 2 to 'BOOL'; the only well defined values for 'BOOL' are YES and NO}}
49+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp