[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2018-07-16 Thread Jordan Rose via Phabricator via cfe-commits
jordan_rose added inline comments.



Comment at: test/Sema/conditional-expr.c:20
   vp = 0 ? (double *)0 : (void *)0;
-  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer 
types assigning to 'int *' from 'double *'}}
+  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer 
types assigning to 'int *' from 'double * _Nullable'}}
 

ahatanak wrote:
> ahatanak wrote:
> > jordan_rose wrote:
> > > This seems like an unfortunate change to make, since most people do not 
> > > bother with nullability.
> > Yes, this is unfortunate, but I'm not sure what's the right way to avoid 
> > printing nullability specifiers in the diagnostic message. Do you have any 
> > suggestions?
> It looks like I can use PrintingPolicy to print the nullability specifier 
> only when needed.
> 
> I think it's also possible to add a flag to Expr that indicates the Expr is 
> possibly null. For example, when an Expr is an IntegerLiteral of value 0, or 
> a CastExpr or a ConditionalOperator has a subexpression whose flag is set. 
> This could be a better solution than the current solution in this patch.
Whew. I hadn't had the chance to look at PrintingPolicy and was afraid you'd 
have to add a new flag to diagnostics or something to specify whether 
nullability was relevant.

An additional flag on Expr seems like overkill to me, given that 
`isNullPointerConstant` already exists. But I don't work in Clang these days, 
so maybe I'm wrong and it is something worth caching. 


Repository:
  rC Clang

https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2018-07-16 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak added inline comments.



Comment at: test/Sema/conditional-expr.c:20
   vp = 0 ? (double *)0 : (void *)0;
-  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer 
types assigning to 'int *' from 'double *'}}
+  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer 
types assigning to 'int *' from 'double * _Nullable'}}
 

ahatanak wrote:
> jordan_rose wrote:
> > This seems like an unfortunate change to make, since most people do not 
> > bother with nullability.
> Yes, this is unfortunate, but I'm not sure what's the right way to avoid 
> printing nullability specifiers in the diagnostic message. Do you have any 
> suggestions?
It looks like I can use PrintingPolicy to print the nullability specifier only 
when needed.

I think it's also possible to add a flag to Expr that indicates the Expr is 
possibly null. For example, when an Expr is an IntegerLiteral of value 0, or a 
CastExpr or a ConditionalOperator has a subexpression whose flag is set. This 
could be a better solution than the current solution in this patch.


Repository:
  rC Clang

https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2018-07-11 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added inline comments.



Comment at: test/Analysis/nullability_nullonly.mm:103
 void testObjCARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning 
{{nil assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning 
{{nil assigned to a pointer which is expected to have non-null value}} 
expected-warning{{implicitly casting a null constant to non-nullable pointer 
type 'TestObject * _Nonnull __strong'}}
 }

ahatanak wrote:
> NoQ wrote:
> > jordan_rose wrote:
> > > @dergachev.a, what do you think here? Is it okay that the analyzer 
> > > diagnoses this in addition to the new warning?
> > We're usually trying to avoid this when we notice it, but there are many 
> > cases where we didn't notice it because both warnings and the analyzer are 
> > becoming better independently. I guess you could just give us a heads up 
> > with a bug report if you don't want to bother with this.
> > 
> > In this case i think it should be easy to fix though, because the analyzer 
> > already has `static isARCNilInitializedLocal()` that suppresses implicit 
> > null initializers, we could teach it to suppress all null initializers 
> > instead.
> I think the warning in nullability-no-arc.mm should be suppressed too? I made 
> changes to isARCNilInitializedLocal so that it returns true when the 
> initializer is explicit or when it is not ARC. I'm not sure whether this is 
> the right way to fix it, but it doesn't cause any regression tests to fail.
Yep, that makes sense, thank you!

It seems that we also need to check that the initializer is a null/nil literal, 
in a manner similar to how the warning checks it, otherwise we lose an analyzer 
positive on
```
int *foo() {
  int *x = 0;
  int *_Nonnull y = x; // expected-warning{{Null assigned to a pointer which is 
expected to have non-null value}}
  return y;
}
```
(which wasn't there in the test suite, so i had to make it up)

And i guess you'll need to rename the function and update comments, and 
parameter `C` also becomes unused (not sure it'll remain this way when the 
aforementioned test is fixed).


Repository:
  rC Clang

https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2018-07-10 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:11103
 
+  if (const auto *DeclRef = dyn_cast(LHSExpr))
+checkNullConstantToNonNull(DeclRef->getType(), RHS.get());

jordan_rose wrote:
> This could come later, but what about struct members or ObjC properties or 
> ObjC subscripts? Seems like you could just check the type of the LHS.
I removed the check for DeclRef so that it warns on struct members (see test 
case in null_constant_to_nonnull.c). 

CheckNonNullArgument already checks null arguments passed to ObjC properties 
and subscripts setter methods. I added a new test case to 
test/SemaObjC/nullability.m.



Comment at: test/Analysis/nullability_nullonly.mm:103
 void testObjCARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning 
{{nil assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning 
{{nil assigned to a pointer which is expected to have non-null value}} 
expected-warning{{implicitly casting a null constant to non-nullable pointer 
type 'TestObject * _Nonnull __strong'}}
 }

NoQ wrote:
> jordan_rose wrote:
> > @dergachev.a, what do you think here? Is it okay that the analyzer 
> > diagnoses this in addition to the new warning?
> We're usually trying to avoid this when we notice it, but there are many 
> cases where we didn't notice it because both warnings and the analyzer are 
> becoming better independently. I guess you could just give us a heads up with 
> a bug report if you don't want to bother with this.
> 
> In this case i think it should be easy to fix though, because the analyzer 
> already has `static isARCNilInitializedLocal()` that suppresses implicit null 
> initializers, we could teach it to suppress all null initializers instead.
I think the warning in nullability-no-arc.mm should be suppressed too? I made 
changes to isARCNilInitializedLocal so that it returns true when the 
initializer is explicit or when it is not ARC. I'm not sure whether this is the 
right way to fix it, but it doesn't cause any regression tests to fail.



Comment at: test/Sema/conditional-expr.c:20
   vp = 0 ? (double *)0 : (void *)0;
-  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer 
types assigning to 'int *' from 'double *'}}
+  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer 
types assigning to 'int *' from 'double * _Nullable'}}
 

jordan_rose wrote:
> This seems like an unfortunate change to make, since most people do not 
> bother with nullability.
Yes, this is unfortunate, but I'm not sure what's the right way to avoid 
printing nullability specifiers in the diagnostic message. Do you have any 
suggestions?


Repository:
  rC Clang

https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2018-07-10 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak updated this revision to Diff 154908.
ahatanak marked 3 inline comments as done.
ahatanak added a comment.

Address review comments.


Repository:
  rC Clang

https://reviews.llvm.org/D22391

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
  test/Analysis/nullability-no-arc.mm
  test/Analysis/nullability.mm
  test/Analysis/nullability_nullonly.mm
  test/Sema/conditional-expr.c
  test/Sema/null_constant_to_nonnull.c
  test/SemaObjC/nullability.m

Index: test/SemaObjC/nullability.m
===
--- test/SemaObjC/nullability.m
+++ test/SemaObjC/nullability.m
@@ -38,6 +38,7 @@
 // expected-note@-1{{use nullability type specifier '_Nonnull' to affect the innermost pointer type of 'NSFoo **'}}
 - (nonnull NSFoo * _Nullable)conflictingMethod1; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}}
 - (nonnull NSFoo * _Nonnull)redundantMethod1; // expected-warning{{duplicate nullability specifier '_Nonnull'}}
+- (void)setObject:(id _Nonnull)object atIndexedSubscript:(int)index;
 
 @property(nonnull,retain) NSFoo *property1;
 @property(nullable,assign) NSFoo ** invalidProperty1; // expected-error{{nullability keyword 'nullable' cannot be applied to multi-level pointer type 'NSFoo **'}}
@@ -65,6 +66,7 @@
   [bar setProperty1: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
   [bar setProperty2: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
   int *ptr = bar.property1; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * _Nonnull'}}
+  bar[1] = 0; // expected-warning{{null passed to a callee that requires a non-null argument}}
 }
 
 // Check returning nil from a nonnull-returning method.
@@ -84,6 +86,9 @@
   int *ip = 0;
   return ip; // expected-warning{{result type 'NSFoo * _Nonnull'}}
 }
+- (void)setObject:(id _Nonnull)object atIndexedSubscript:(int)index {
+}
+
 @end
 
 __attribute__((objc_root_class))
Index: test/Sema/null_constant_to_nonnull.c
===
--- /dev/null
+++ test/Sema/null_constant_to_nonnull.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -Wnullable-to-nonnull-conversion %s -verify
+
+struct S {
+  int * _Nonnull f;
+};
+
+void null_const_to_nonnull(int c, struct S *s) {
+  int * _Nonnull p0 = 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  p0 = 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  p0 = (int * _Nonnull)0; // explicit cast silences warnings
+  int * _Nonnull p1;
+  int * _Nonnull p2 = c ? p1 : 0; // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}}
+  p2 = c ? p1 : (int * _Nonnull)0; // explicit cast silences warnings
+  s->f = 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+}
Index: test/Sema/conditional-expr.c
===
--- test/Sema/conditional-expr.c
+++ test/Sema/conditional-expr.c
@@ -17,7 +17,7 @@
   dp = ip; // expected-warning {{incompatible pointer types assigning to 'double *' from 'int *'}}
   dp = 0 ? (double *)0 : (void *)0;
   vp = 0 ? (double *)0 : (void *)0;
-  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer types assigning to 'int *' from 'double *'}}
+  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer types assigning to 'int *' from 'double * _Nullable'}}
 
   const int *cip;
   vp = (0 ? vp : cip); // expected-warning {{discards qualifiers}}
@@ -90,7 +90,7 @@
 
 int f0(int a) {
   // GCC considers this a warning.
-  return a ? f1() : nil; // expected-warning {{pointer/integer type mismatch in conditional expression ('int' and 'void *')}} expected-warning {{incompatible pointer to integer conversion returning 'void *' from a function with result type 'int'}}
+  return a ? f1() : nil; // expected-warning {{pointer/integer type mismatch in conditional expression ('int' and 'void *')}} expected-warning {{incompatible pointer to integer conversion returning 'void * _Nullable' from a function with result type 'int'}}
 }
 
 int f2(int x) {
Index: test/Analysis/nullability_nullonly.mm
===
--- test/Analysis/nullability_nullonly.mm
+++ test/Analysis/nullability_nullonly.mm
@@ -100,7 +100,7 @@
 }
 
 void testObjCARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer 

[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2018-07-10 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ edited subscribers, added: NoQ; removed: dergachev.a.
NoQ added inline comments.



Comment at: test/Analysis/nullability_nullonly.mm:103
 void testObjCARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning 
{{nil assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning 
{{nil assigned to a pointer which is expected to have non-null value}} 
expected-warning{{implicitly casting a null constant to non-nullable pointer 
type 'TestObject * _Nonnull __strong'}}
 }

jordan_rose wrote:
> @dergachev.a, what do you think here? Is it okay that the analyzer diagnoses 
> this in addition to the new warning?
We're usually trying to avoid this when we notice it, but there are many cases 
where we didn't notice it because both warnings and the analyzer are becoming 
better independently. I guess you could just give us a heads up with a bug 
report if you don't want to bother with this.

In this case i think it should be easy to fix though, because the analyzer 
already has `static isARCNilInitializedLocal()` that suppresses implicit null 
initializers, we could teach it to suppress all null initializers instead.


Repository:
  rC Clang

https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2018-07-10 Thread Jordan Rose via Phabricator via cfe-commits
jordan_rose added a subscriber: dergachev.a.
jordan_rose added a comment.

Sorry for the delay. I think this is mostly good, but I do still have a concern 
about the diagnostics change.




Comment at: lib/Sema/SemaExpr.cpp:7117
+if (E && S.checkNonNullExpr(E))
+  return NullabilityKind::Nullable;
+

ahatanak wrote:
> jordan_rose wrote:
> > This isn't quite correct, unfortunately. `(_Nonnull id)nil` should be 
> > considered non-nullable, since it's the canonical way to avoid all these 
> > warnings. It might just be good enough to move this check below the 
> > `getNullability` one, though.
> Sema::CheckNonNullExpr checks the nullability of the type of the expression 
> first and returns false if there is a cast to `_Nonnull`.
Hm, okay, I see you have a test. Sorry for the noise.



Comment at: lib/Sema/SemaExpr.cpp:7162
+  bool IsBin, Expr *LHSExpr,
+  Expr *RHSExpr, ASTContext ) {
   if (!ResTy->isAnyPointerType())

Nitpick: you could use `const` on the Exprs here.



Comment at: lib/Sema/SemaExpr.cpp:11103
 
+  if (const auto *DeclRef = dyn_cast(LHSExpr))
+checkNullConstantToNonNull(DeclRef->getType(), RHS.get());

This could come later, but what about struct members or ObjC properties or ObjC 
subscripts? Seems like you could just check the type of the LHS.



Comment at: test/Analysis/nullability_nullonly.mm:103
 void testObjCARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning 
{{nil assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning 
{{nil assigned to a pointer which is expected to have non-null value}} 
expected-warning{{implicitly casting a null constant to non-nullable pointer 
type 'TestObject * _Nonnull __strong'}}
 }

@dergachev.a, what do you think here? Is it okay that the analyzer diagnoses 
this in addition to the new warning?



Comment at: test/Sema/conditional-expr.c:20
   vp = 0 ? (double *)0 : (void *)0;
-  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer 
types assigning to 'int *' from 'double *'}}
+  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer 
types assigning to 'int *' from 'double * _Nullable'}}
 

This seems like an unfortunate change to make, since most people do not bother 
with nullability.


Repository:
  rC Clang

https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2018-07-09 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak added a comment.
Herald added a subscriber: dexonsmith.

ping


Repository:
  rC Clang

https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2018-06-06 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak added inline comments.



Comment at: lib/Sema/SemaExpr.cpp:7117
+if (E && S.checkNonNullExpr(E))
+  return NullabilityKind::Nullable;
+

jordan_rose wrote:
> This isn't quite correct, unfortunately. `(_Nonnull id)nil` should be 
> considered non-nullable, since it's the canonical way to avoid all these 
> warnings. It might just be good enough to move this check below the 
> `getNullability` one, though.
Sema::CheckNonNullExpr checks the nullability of the type of the expression 
first and returns false if there is a cast to `_Nonnull`.


Repository:
  rC Clang

https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2018-06-06 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak updated this revision to Diff 150218.
ahatanak marked an inline comment as done.
ahatanak added a reviewer: dcoughlin.
ahatanak set the repository for this revision to rC Clang.
ahatanak added a comment.

Sorry for the delay in responding. I've addressed Jordan's review comments.

I had to make changes to a couple of tests in Analysis. In particular, I'm not 
sure whether we should try to avoid producing extra diagnostics in 
test/Analysis/nullability_nullonly.mm or whether it's possible to do so in Sema.


Repository:
  rC Clang

https://reviews.llvm.org/D22391

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  test/Analysis/nullability-no-arc.mm
  test/Analysis/nullability.mm
  test/Analysis/nullability_nullonly.mm
  test/Sema/conditional-expr.c
  test/Sema/null_constant_to_nonnull.c

Index: test/Sema/null_constant_to_nonnull.c
===
--- /dev/null
+++ test/Sema/null_constant_to_nonnull.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -Wnullable-to-nonnull-conversion %s -verify
+
+void null_const_to_nonnull(int c) {
+  int * _Nonnull p0 = 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  p0 = 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  p0 = (int * _Nonnull)0; // explicit cast silences warnings
+  int * _Nonnull p1;
+  int * _Nonnull p2 = c ? p1 : 0; // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}}
+  p2 = c ? p1 : (int * _Nonnull)0; // explicit cast silences warnings
+}
Index: test/Sema/conditional-expr.c
===
--- test/Sema/conditional-expr.c
+++ test/Sema/conditional-expr.c
@@ -17,7 +17,7 @@
   dp = ip; // expected-warning {{incompatible pointer types assigning to 'double *' from 'int *'}}
   dp = 0 ? (double *)0 : (void *)0;
   vp = 0 ? (double *)0 : (void *)0;
-  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer types assigning to 'int *' from 'double *'}}
+  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer types assigning to 'int *' from 'double * _Nullable'}}
 
   const int *cip;
   vp = (0 ? vp : cip); // expected-warning {{discards qualifiers}}
@@ -90,7 +90,7 @@
 
 int f0(int a) {
   // GCC considers this a warning.
-  return a ? f1() : nil; // expected-warning {{pointer/integer type mismatch in conditional expression ('int' and 'void *')}} expected-warning {{incompatible pointer to integer conversion returning 'void *' from a function with result type 'int'}}
+  return a ? f1() : nil; // expected-warning {{pointer/integer type mismatch in conditional expression ('int' and 'void *')}} expected-warning {{incompatible pointer to integer conversion returning 'void * _Nullable' from a function with result type 'int'}}
 }
 
 int f2(int x) {
Index: test/Analysis/nullability_nullonly.mm
===
--- test/Analysis/nullability_nullonly.mm
+++ test/Analysis/nullability_nullonly.mm
@@ -100,7 +100,7 @@
 }
 
 void testObjCARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'TestObject * _Nonnull __strong'}}
 }
 
 // Under ARC, returned expressions of ObjC objects types are are implicitly
Index: test/Analysis/nullability.mm
===
--- test/Analysis/nullability.mm
+++ test/Analysis/nullability.mm
@@ -180,7 +180,7 @@
 
   // Since we've already had an invariant violation along this path,
   // we shouldn't warn here.
-  nonnullLocalWithAssignmentInInitializer = 0;
+  nonnullLocalWithAssignmentInInitializer = 0; // expected-warning {{implicitly casting a null constant to non-nullable pointer type}}
   (void)nonnullLocalWithAssignmentInInitializer;
 
 }
@@ -192,7 +192,7 @@
 
   // Since we've already had an invariant violation along this path,
   // we shouldn't warn here.
-  nonnullLocalWithAssignment = 0;
+  nonnullLocalWithAssignment = 0; // expected-warning {{implicitly casting a null constant to non-nullable pointer type}}
   (void)nonnullLocalWithAssignment;
 }
 
Index: test/Analysis/nullability-no-arc.mm
===
--- test/Analysis/nullability-no-arc.mm
+++ test/Analysis/nullability-no-arc.mm
@@ -43,7 +43,7 @@
 }
 
 void 

[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2017-03-22 Thread Jordan Rose via Phabricator via cfe-commits
jordan_rose added a comment.

This looks like it's only coming up for declarations. What about assignments?

  int x;
  int * _Nonnull p = 
  p = NULL; // warn here?




Comment at: lib/Sema/SemaExpr.cpp:7117
+if (E && S.checkNonNullExpr(E))
+  return NullabilityKind::Nullable;
+

This isn't quite correct, unfortunately. `(_Nonnull id)nil` should be 
considered non-nullable, since it's the canonical way to avoid all these 
warnings. It might just be good enough to move this check below the 
`getNullability` one, though.


https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2017-03-21 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak updated this revision to Diff 92583.
ahatanak added a comment.

Rebase and ping.


https://reviews.llvm.org/D22391

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  test/Analysis/nullability-no-arc.mm
  test/Analysis/nullability_nullonly.mm
  test/Sema/conditional-expr.c
  test/Sema/null_constant_to_nonnull.c

Index: test/Sema/null_constant_to_nonnull.c
===
--- /dev/null
+++ test/Sema/null_constant_to_nonnull.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -Wnullable-to-nonnull-conversion %s -verify
+
+void null_const_to_nonnull(int c) {
+  int * _Nonnull p0 = 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  int * _Nonnull p1;
+  int * _Nonnull p2 = c ? p1 : 0; // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}}
+}
Index: test/Sema/conditional-expr.c
===
--- test/Sema/conditional-expr.c
+++ test/Sema/conditional-expr.c
@@ -17,7 +17,7 @@
   dp = ip; // expected-warning {{incompatible pointer types assigning to 'double *' from 'int *'}}
   dp = 0 ? (double *)0 : (void *)0;
   vp = 0 ? (double *)0 : (void *)0;
-  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer types assigning to 'int *' from 'double *'}}
+  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer types assigning to 'int *' from 'double * _Nullable'}}
 
   const int *cip;
   vp = (0 ? vp : cip); // expected-warning {{discards qualifiers}}
@@ -90,7 +90,7 @@
 
 int f0(int a) {
   // GCC considers this a warning.
-  return a ? f1() : nil; // expected-warning {{pointer/integer type mismatch in conditional expression ('int' and 'void *')}} expected-warning {{incompatible pointer to integer conversion returning 'void *' from a function with result type 'int'}}
+  return a ? f1() : nil; // expected-warning {{pointer/integer type mismatch in conditional expression ('int' and 'void *')}} expected-warning {{incompatible pointer to integer conversion returning 'void * _Nullable' from a function with result type 'int'}}
 }
 
 int f2(int x) {
Index: test/Analysis/nullability_nullonly.mm
===
--- test/Analysis/nullability_nullonly.mm
+++ test/Analysis/nullability_nullonly.mm
@@ -100,7 +100,7 @@
 }
 
 void testObjCARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'TestObject * _Nonnull __strong'}}
 }
 
 // Under ARC, returned expressions of ObjC objects types are are implicitly
Index: test/Analysis/nullability-no-arc.mm
===
--- test/Analysis/nullability-no-arc.mm
+++ test/Analysis/nullability-no-arc.mm
@@ -43,7 +43,7 @@
 }
 
 void testObjCNonARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}} expected-warning {{implicitly casting a null constant to non-nullable pointer type 'TestObject * _Nonnull'}}
 }
 
 @interface ClassWithInitializers : NSObject
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -7105,20 +7105,26 @@
 }
 
 /// Compute the nullability of a conditional expression.
-static QualType computeConditionalNullability(QualType ResTy, bool IsBin,
-  QualType LHSTy, QualType RHSTy,
-  ASTContext ) {
+static QualType computeConditionalNullability(Sema , QualType ResTy,
+  bool IsBin, Expr *LHSExpr,
+  Expr *RHSExpr, ASTContext ) {
   if (!ResTy->isAnyPointerType())
 return ResTy;
 
-  auto GetNullability = [](QualType Ty) {
+  auto GetNullability = [, ](QualType Ty, Expr *E = nullptr) {
+// If E evaluates to a null constant, return nullable.
+if (E && S.checkNonNullExpr(E))
+  return NullabilityKind::Nullable;
+
 Optional Kind = Ty->getNullability(Ctx);
 if (Kind)
   return *Kind;
 return NullabilityKind::Unspecified;
   

[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2017-02-03 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak updated this revision to Diff 87016.
ahatanak marked 2 inline comments as done.
ahatanak added a comment.

Turning the warning on by default caused clang to issue warnings in many other 
cases, including Objective-C methods returning nil, which was something r240153 
tried to avoid. If we want to disable the warning in Sema::ImpCastExprToType 
when the cast is part of a return statement of an ObjC method, we'll probably 
have to pass down a flag or something, which is probably not a good idea.

Instead of trying to issue the warning in Sema::ImpCastExprToType, the new 
patch checks whether there is a null constant in Sema::AddInitializerToDecl 
(which is needed to issue the first warning in null_constant_to_nonnull.c) and 
computeConditionalNullability (which is needed for the second warning). Also, 
it adds method Sema::checkNonNullExpr so that CheckNonNullExpr can be called 
from files other than SemaChecking.cpp.


https://reviews.llvm.org/D22391

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  test/Analysis/nullability-no-arc.mm
  test/Analysis/nullability_nullonly.mm
  test/Sema/conditional-expr.c
  test/Sema/null_constant_to_nonnull.c

Index: test/Sema/null_constant_to_nonnull.c
===
--- /dev/null
+++ test/Sema/null_constant_to_nonnull.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -Wnullable-to-nonnull-conversion %s -verify
+
+void null_const_to_nonnull(int c) {
+  int * _Nonnull p0 = 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  int * _Nonnull p1;
+  int * _Nonnull p2 = c ? p1 : 0; // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}}
+}
Index: test/Sema/conditional-expr.c
===
--- test/Sema/conditional-expr.c
+++ test/Sema/conditional-expr.c
@@ -17,7 +17,7 @@
   dp = ip; // expected-warning {{incompatible pointer types assigning to 'double *' from 'int *'}}
   dp = 0 ? (double *)0 : (void *)0;
   vp = 0 ? (double *)0 : (void *)0;
-  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer types assigning to 'int *' from 'double *'}}
+  ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer types assigning to 'int *' from 'double * _Nullable'}}
 
   const int *cip;
   vp = (0 ? vp : cip); // expected-warning {{discards qualifiers}}
@@ -90,7 +90,7 @@
 
 int f0(int a) {
   // GCC considers this a warning.
-  return a ? f1() : nil; // expected-warning {{pointer/integer type mismatch in conditional expression ('int' and 'void *')}} expected-warning {{incompatible pointer to integer conversion returning 'void *' from a function with result type 'int'}}
+  return a ? f1() : nil; // expected-warning {{pointer/integer type mismatch in conditional expression ('int' and 'void *')}} expected-warning {{incompatible pointer to integer conversion returning 'void * _Nullable' from a function with result type 'int'}}
 }
 
 int f2(int x) {
Index: test/Analysis/nullability_nullonly.mm
===
--- test/Analysis/nullability_nullonly.mm
+++ test/Analysis/nullability_nullonly.mm
@@ -100,7 +100,7 @@
 }
 
 void testObjCARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'TestObject * _Nonnull __strong'}}
 }
 
 // Under ARC, returned expressions of ObjC objects types are are implicitly
Index: test/Analysis/nullability-no-arc.mm
===
--- test/Analysis/nullability-no-arc.mm
+++ test/Analysis/nullability-no-arc.mm
@@ -43,7 +43,7 @@
 }
 
 void testObjCNonARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}} expected-warning {{implicitly casting a null constant to non-nullable pointer type 'TestObject * _Nonnull'}}
 }
 
 @interface ClassWithInitializers : NSObject
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -7097,20 +7097,26 @@
 }
 
 /// Compute the nullability of a conditional expression.
-static QualType 

[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2017-01-24 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak added inline comments.



Comment at: include/clang/Basic/DiagnosticGroups.td:290
 def NullableToNonNullConversion : DiagGroup<"nullable-to-nonnull-conversion">;
+def NullConstToNonnull : DiagGroup<"null-const-to-nonnull">;
 def NullabilityCompletenessOnArrays : 
DiagGroup<"nullability-completeness-on-arrays">;

jordan_rose wrote:
> Nitpick: Using "const" here makes me think of the qualifier. Is there a 
> reason not to just spell out "constant"?
I probably just wanted it to be shorter, but I'll change it to constant as you 
suggested.



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:8807
+  "implicitly casting a null constant to non-nullable pointer type %0">,
+  InGroup, DefaultIgnore;
+

jordan_rose wrote:
> Why "DefaultIgnore"? This seems like a good warning to be on all the time.
I think I added DefaultIgnore just because the one above 
(warn_nullability_lost) had it too. I agree that it probably should be on all 
the time.


https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2017-01-24 Thread Jordan Rose via Phabricator via cfe-commits
jordan_rose added inline comments.



Comment at: include/clang/Basic/DiagnosticGroups.td:290
 def NullableToNonNullConversion : DiagGroup<"nullable-to-nonnull-conversion">;
+def NullConstToNonnull : DiagGroup<"null-const-to-nonnull">;
 def NullabilityCompletenessOnArrays : 
DiagGroup<"nullability-completeness-on-arrays">;

Nitpick: Using "const" here makes me think of the qualifier. Is there a reason 
not to just spell out "constant"?



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:8807
+  "implicitly casting a null constant to non-nullable pointer type %0">,
+  InGroup, DefaultIgnore;
+

Why "DefaultIgnore"? This seems like a good warning to be on all the time.


https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2017-01-24 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak updated this revision to Diff 85651.
ahatanak added a reviewer: jordan_rose.
ahatanak added a comment.

Rebase.


https://reviews.llvm.org/D22391

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/Sema.cpp
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaExpr.cpp
  test/Sema/null_const_to_nonnull.c

Index: test/Sema/null_const_to_nonnull.c
===
--- /dev/null
+++ test/Sema/null_const_to_nonnull.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -Wnull-const-to-nonnull %s -verify
+
+void null_const_to_nonnull(int c) {
+  int * _Nonnull p0 = 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  int * _Nonnull p1;
+  int * _Nonnull p2 = c ? p1 : 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+}
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -717,6 +717,7 @@
   E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
 Cleanup.setExprNeedsCleanups(true);
 
+  diagnoseNullPtrToNonnullCast(T, E, E->getExprLoc());
   ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
 nullptr, VK_RValue);
 
Index: lib/Sema/SemaChecking.cpp
===
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -9475,6 +9475,17 @@
   return false;
 }
 
+void Sema::diagnoseNullPtrToNonnullCast(QualType DstType, Expr *E,
+SourceLocation Loc) {
+  if (!DstType->isAnyPointerType() || CurContext->isDependentContext())
+return;
+
+  if (Optional Kind = DstType->getNullability(Context))
+if (*Kind == NullabilityKind::NonNull &&
+E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
+  Diag(Loc, diag::warn_null_const_to_nonnull) << DstType;
+}
+
 /// \brief Diagnose pointers that are always non-null.
 /// \param E the expression containing the pointer
 /// \param NullKind NPCK_NotNull if E is a cast to bool, otherwise, E is
Index: lib/Sema/Sema.cpp
===
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -441,6 +441,7 @@
 }
   }
 
+  diagnoseNullPtrToNonnullCast(Ty, E, E->getExprLoc());
   return ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK);
 }
 
Index: include/clang/Sema/Sema.h
===
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -3729,6 +3729,11 @@
   void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType,
SourceLocation Loc);
 
+  /// Warn if we're implicitly casting from a null pointer constant to a
+  /// _Nonnull pointer type.
+  void diagnoseNullPtrToNonnullCast(QualType DstType, Expr *E,
+SourceLocation Loc);
+
   ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool ) {
 return DelayedDiagnostics.push(pool);
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -8802,6 +8802,10 @@
   "type %1">,
   InGroup, DefaultIgnore;
 
+def warn_null_const_to_nonnull : Warning<
+  "implicitly casting a null constant to non-nullable pointer type %0">,
+  InGroup, DefaultIgnore;
+
 def err_nullability_cs_multilevel : Error<
   "nullability keyword %0 cannot be applied to multi-level pointer type %1">;
 def note_nullability_type_specifier : Note<
Index: include/clang/Basic/DiagnosticGroups.td
===
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -287,6 +287,7 @@
 def NullabilityDeclSpec : DiagGroup<"nullability-declspec">;
 def NullabilityInferredOnNestedType : DiagGroup<"nullability-inferred-on-nested-type">;
 def NullableToNonNullConversion : DiagGroup<"nullable-to-nonnull-conversion">;
+def NullConstToNonnull : DiagGroup<"null-const-to-nonnull">;
 def NullabilityCompletenessOnArrays : DiagGroup<"nullability-completeness-on-arrays">;
 def NullabilityCompleteness : DiagGroup<"nullability-completeness",
 [NullabilityCompletenessOnArrays]>;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2016-07-25 Thread Akira Hatanaka via cfe-commits
ahatanak updated this revision to Diff 65446.
ahatanak added a comment.

Addressed review comment and made a couple of other changes.

- Move Sema::diagnoseNullPtrToNonnullCast to SemaChecking.cpp.
- In diagnoseNullPtrToNonnullCast, call "Type::isAnyPointerType" instead of 
"Type::isPointerType" so that the function can diagnose objective-c pointers in 
addition to c/c++ pointers.
- Instead of adding the new warning to the existing 
"NullableToNonNullConversion" group, which would cause clang to warn about nil 
returns from objective-c methods (which is undesirable according to r240153's 
commit log), create a new diagnostic group for "-Wnull-const_to-nonnull".


https://reviews.llvm.org/D22391

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/Sema.cpp
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaExpr.cpp
  test/Sema/null_const_to_nonnull.c
  test/SemaObjC/null_const_to_nonnull.m

Index: test/SemaObjC/null_const_to_nonnull.m
===
--- /dev/null
+++ test/SemaObjC/null_const_to_nonnull.m
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -Wnull-const-to-nonnull %s -verify
+
+void null_const_to_nonnull(int c) {
+  id _Nonnull p0 = 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'id _Nonnull'}}
+  id _Nonnull p1;
+  id _Nonnull p2 = c ? p1 : 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'id _Nonnull'}}
+}
Index: test/Sema/null_const_to_nonnull.c
===
--- /dev/null
+++ test/Sema/null_const_to_nonnull.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -Wnull-const-to-nonnull %s -verify
+
+void null_const_to_nonnull(int c) {
+  int * _Nonnull p0 = 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  int * _Nonnull p1;
+  int * _Nonnull p2 = c ? p1 : 0; // expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+}
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -714,6 +714,7 @@
   E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
 Cleanup.setExprNeedsCleanups(true);
 
+  diagnoseNullPtrToNonnullCast(T, E, E->getExprLoc());
   ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
 nullptr, VK_RValue);
 
Index: lib/Sema/SemaChecking.cpp
===
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -8685,6 +8685,17 @@
   return false;
 }
 
+void Sema::diagnoseNullPtrToNonnullCast(QualType DstType, Expr *E,
+SourceLocation Loc) {
+  if (!DstType->isAnyPointerType() || CurContext->isDependentContext())
+return;
+
+  if (Optional Kind = DstType->getNullability(Context))
+if (*Kind == NullabilityKind::NonNull &&
+E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
+  Diag(Loc, diag::warn_null_const_to_nonnull) << DstType;
+}
+
 /// \brief Diagnose pointers that are always non-null.
 /// \param E the expression containing the pointer
 /// \param NullKind NPCK_NotNull if E is a cast to bool, otherwise, E is
Index: lib/Sema/Sema.cpp
===
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -399,6 +399,7 @@
 }
   }
 
+  diagnoseNullPtrToNonnullCast(Ty, E, E->getExprLoc());
   return ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK);
 }
 
Index: include/clang/Sema/Sema.h
===
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -3614,6 +3614,11 @@
   void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType,
SourceLocation Loc);
 
+  /// Warn if we're implicitly casting from a null pointer constant to a
+  /// _Nonnull pointer type.
+  void diagnoseNullPtrToNonnullCast(QualType DstType, Expr *E,
+SourceLocation Loc);
+
   ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool ) {
 return DelayedDiagnostics.push(pool);
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -8538,6 +8538,10 @@
   "type %1">,
   InGroup, DefaultIgnore;
 
+def warn_null_const_to_nonnull : Warning<
+  "implicitly casting a null constant to non-nullable pointer type %0">,
+  InGroup, DefaultIgnore;
+
 def err_nullability_cs_multilevel : Error<
   "nullability keyword %0 cannot be applied to multi-level pointer type %1">;
 

Re: [PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2016-07-14 Thread Doug Gregor via cfe-commits
doug.gregor added a comment.

I think this check should go into SemaChecking.cpp


https://reviews.llvm.org/D22391



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22391: [Sema] Add warning for implicitly casting a null constant to a non null pointer type

2016-07-14 Thread Akira Hatanaka via cfe-commits
ahatanak created this revision.
ahatanak added a reviewer: doug.gregor.
ahatanak added a subscriber: cfe-commits.

This patch makes clang issue a warning when a null constant is used in a 
context where a non null expression is expected. For example:

```
int * _Nonnull p0 = 0; // warning expected here
int * _Nonnull p1;
int * _Nonnull p2 = c ? p1 : 0; // warning expected here
```

A new function Sema::diagnoseNullPtrToNonnullCast is defined, which checks 
whether a null pointer constant is being cast to a _Nonnull pointer type, and 
called before ImplicitCastExprs are created.

rdar://problem/24724255
rdar://problem/22074116



https://reviews.llvm.org/D22391

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/Sema.cpp
  lib/Sema/SemaExpr.cpp
  test/Sema/nullability.c
  test/SemaCXX/nullability.cpp

Index: test/SemaCXX/nullability.cpp
===
--- test/SemaCXX/nullability.cpp
+++ test/SemaCXX/nullability.cpp
@@ -54,16 +54,16 @@
 void (_nonnull_5)(_Nonnull int *ptr) = accepts_nonnull_4;
 
 void test_accepts_nonnull_null_pointer_literal(X *x) {
-  accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
-  accepts_nonnull_2(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
-  (x->*accepts_nonnull_3)(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
-  accepts_nonnull_4(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
-  accepts_nonnull_5(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
+  accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  accepts_nonnull_2(0); // expected-warning{{null passed to a callee that requires a non-null argument}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  (x->*accepts_nonnull_3)(0); // expected-warning{{null passed to a callee that requires a non-null argument}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  accepts_nonnull_4(0); // expected-warning{{null passed to a callee that requires a non-null argument}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
+  accepts_nonnull_5(0); // expected-warning{{null passed to a callee that requires a non-null argument}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
 }
 
 template 
 void test_accepts_nonnull_null_pointer_literal_template() {
-  FP(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
+  FP(0); // expected-warning{{null passed to a callee that requires a non-null argument}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull'}}
 }
 
 template void test_accepts_nonnull_null_pointer_literal_template<_nonnull_4>(); // expected-note{{instantiation of function template specialization}}
Index: test/Sema/nullability.c
===
--- test/Sema/nullability.c
+++ test/Sema/nullability.c
@@ -106,15 +106,15 @@
 void (^accepts_nonnull_3)(_Nonnull int *ptr);
 
 void test_accepts_nonnull_null_pointer_literal() {
-  accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
-  accepts_nonnull_2(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
-  accepts_nonnull_3(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
+  accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull}}
+  accepts_nonnull_2(0); // expected-warning{{null passed to a callee that requires a non-null argument}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull}}
+  accepts_nonnull_3(0); // expected-warning{{null passed to a callee that requires a non-null argument}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull}}
 }
 
 // Check returning nil from a _Nonnull-returning function.
 _Nonnull int *returns_int_ptr(int x) {
   if (x) {
-return 0; // expected-warning{{null returned from function that requires a non-null return value}}
+return 0; // expected-warning{{null returned from function that requires a non-null return value}} expected-warning{{implicitly casting a null constant to non-nullable pointer type 'int * _Nonnull}}
   }
 
   return (_Nonnull int *)0;
@@ -128,3 +128,9 @@
 
   accepts_nonnull_1(ptr); //