2017-03-04 02:02:02 +08:00
|
|
|
// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=text -verify
|
2018-06-13 03:07:41 +08:00
|
|
|
// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=plist -o %t
|
2019-06-11 22:21:32 +08:00
|
|
|
// RUN: %normalize_plist <%t | diff -ub %S/Inputs/expected-plists/conditional-path-notes.c.plist -
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
|
|
|
|
void testCondOp(int *p) {
|
|
|
|
int *x = p ? p : p;
|
|
|
|
// expected-note@-1 {{Assuming 'p' is null}}
|
|
|
|
// expected-note@-2 {{'?' condition is false}}
|
2013-02-27 03:44:38 +08:00
|
|
|
// expected-note@-3 {{'x' initialized to a null pointer value}}
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
*x = 1; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
|
|
|
|
// expected-note@-1 {{Dereference of null pointer (loaded from variable 'x')}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testCondProblem(int *p) {
|
|
|
|
if (p) return;
|
|
|
|
// expected-note@-1 {{Assuming 'p' is null}}
|
2012-10-26 06:07:10 +08:00
|
|
|
// expected-note@-2 {{Taking false branch}}
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
|
|
|
|
int x = *p ? 0 : 1; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
|
|
|
|
// expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
|
|
|
|
(void)x;
|
|
|
|
}
|
|
|
|
|
|
|
|
void testLHSProblem(int *p) {
|
|
|
|
int x = !p ? *p : 1; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
|
|
|
|
// expected-note@-1 {{Assuming 'p' is null}}
|
2012-10-26 06:07:10 +08:00
|
|
|
// expected-note@-2 {{'?' condition is true}}
|
|
|
|
// expected-note@-3 {{Dereference of null pointer (loaded from variable 'p')}}
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
(void)x;
|
|
|
|
}
|
|
|
|
|
|
|
|
void testRHSProblem(int *p) {
|
|
|
|
int x = p ? 1 : *p; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
|
|
|
|
// expected-note@-1 {{Assuming 'p' is null}}
|
2012-10-26 06:07:10 +08:00
|
|
|
// expected-note@-2 {{'?' condition is false}}
|
|
|
|
// expected-note@-3 {{Dereference of null pointer (loaded from variable 'p')}}
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
(void)x;
|
|
|
|
}
|
|
|
|
|
|
|
|
void testBinaryCondOp(int *p) {
|
|
|
|
int *x = p ?: p;
|
|
|
|
// expected-note@-1 {{'?' condition is false}}
|
2013-02-27 03:44:38 +08:00
|
|
|
// expected-note@-2 {{'x' initialized to a null pointer value}}
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
*x = 1; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
|
|
|
|
// expected-note@-1 {{Dereference of null pointer (loaded from variable 'x')}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testBinaryLHSProblem(int *p) {
|
|
|
|
if (p) return;
|
|
|
|
// expected-note@-1 {{Assuming 'p' is null}}
|
2012-10-26 06:07:10 +08:00
|
|
|
// expected-note@-2 {{Taking false branch}}
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
|
|
|
|
int x = *p ?: 1; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
|
|
|
|
// expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
|
|
|
|
(void)x;
|
|
|
|
}
|
|
|
|
|
2013-10-26 09:16:26 +08:00
|
|
|
void testDiagnosableBranch(int a) {
|
|
|
|
if (a) {
|
|
|
|
// expected-note@-1 {{Assuming 'a' is not equal to 0}}
|
|
|
|
// expected-note@-2 {{Taking true branch}}
|
2021-07-09 23:39:40 +08:00
|
|
|
*(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}}
|
2013-10-26 09:16:26 +08:00
|
|
|
// expected-note@-1 {{Dereference of null pointer}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-05 16:28:25 +08:00
|
|
|
void testDiagnosableBranchLogical(int a, int b) {
|
2013-10-26 09:16:26 +08:00
|
|
|
if (a && b) {
|
2016-10-05 16:28:25 +08:00
|
|
|
// expected-note@-1 {{Assuming 'a' is not equal to 0}}
|
2016-10-05 16:19:49 +08:00
|
|
|
// expected-note@-2 {{Left side of '&&' is true}}
|
2016-10-05 16:28:25 +08:00
|
|
|
// expected-note@-3 {{Assuming 'b' is not equal to 0}}
|
|
|
|
// expected-note@-4 {{Taking true branch}}
|
2021-07-09 23:39:40 +08:00
|
|
|
*(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}}
|
2013-10-26 09:16:26 +08:00
|
|
|
// expected-note@-1 {{Dereference of null pointer}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testNonDiagnosableBranchArithmetic(int a, int b) {
|
|
|
|
if (a - b) {
|
2017-07-13 05:43:42 +08:00
|
|
|
// expected-note@-1 {{Taking true branch}}
|
2018-04-11 14:21:12 +08:00
|
|
|
// expected-note@-2 {{Assuming the condition is true}}
|
2021-07-09 23:39:40 +08:00
|
|
|
*(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}}
|
2013-10-26 09:16:26 +08:00
|
|
|
// expected-note@-1 {{Dereference of null pointer}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|