summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2019-07-01 23:02:14 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2019-07-01 23:02:14 +0000
commit512f4838c47c5bab13d8bb0eabc01d64222825ae (patch)
tree254edeea96759e115a9e20b02bcae713b432567c /clang/lib/StaticAnalyzer/Checkers
parent35fdec1b54c6a8b1ca7bee542836abf29c75a85d (diff)
downloadbcm5719-llvm-512f4838c47c5bab13d8bb0eabc01d64222825ae.tar.gz
bcm5719-llvm-512f4838c47c5bab13d8bb0eabc01d64222825ae.zip
[analyzer] NonnullGlobalConstants: Don't be confused by a _Nonnull attribute.
The NonnullGlobalConstants checker models the rule "it doesn't make sense to make a constant global pointer and initialize it to null"; it makes sure that whatever it's initialized with is known to be non-null. Ironically, annotating the type of the pointer as _Nonnull breaks the checker. Fix handling of the _Nonnull annotation so that it was instead one more reason to believe that the value is non-null. Differential Revision: https://reviews.llvm.org/D63956 llvm-svn: 364869
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp23
1 files changed, 15 insertions, 8 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
index dd76fd2f129..43dbe57b843 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
@@ -106,14 +106,21 @@ bool NonnullGlobalConstantsChecker::isGlobalConstString(SVal V) const {
return true;
// Look through the typedefs.
- while (auto *T = dyn_cast<TypedefType>(Ty)) {
- Ty = T->getDecl()->getUnderlyingType();
-
- // It is sufficient for any intermediate typedef
- // to be classified const.
- HasConst = HasConst || Ty.isConstQualified();
- if (isNonnullType(Ty) && HasConst)
- return true;
+ while (const Type *T = Ty.getTypePtr()) {
+ if (const auto *TT = dyn_cast<TypedefType>(T)) {
+ Ty = TT->getDecl()->getUnderlyingType();
+ // It is sufficient for any intermediate typedef
+ // to be classified const.
+ HasConst = HasConst || Ty.isConstQualified();
+ if (isNonnullType(Ty) && HasConst)
+ return true;
+ } else if (const auto *AT = dyn_cast<AttributedType>(T)) {
+ if (AT->getAttrKind() == attr::TypeNonNull)
+ return true;
+ Ty = AT->getModifiedType();
+ } else {
+ return false;
+ }
}
return false;
}
OpenPOWER on IntegriCloud