aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
diff options
context:
space:
mode:
authorGabor Marton <gabor.marton@ericsson.com>2020-09-03 19:08:54 +0200
committerGabor Marton <gabor.marton@ericsson.com>2020-09-04 11:48:38 +0200
commitfe0972d3e4a65b4c5f5fa602b17ad30e463050b3 (patch)
treeb6abbfefc85457fc6982bd0ce478d5eb3c803013 /clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
parenta633da5391b0e42c0185132e8b532ae9bc34489f (diff)
downloadllvm-fe0972d3e4a65b4c5f5fa602b17ad30e463050b3.zip
llvm-fe0972d3e4a65b4c5f5fa602b17ad30e463050b3.tar.gz
llvm-fe0972d3e4a65b4c5f5fa602b17ad30e463050b3.tar.bz2
[analyzer][StdLibraryFunctionsChecker] Do not match based on the restrict qualifier in C++
The "restrict" keyword is illegal in C++, however, many libc implementations use the "__restrict" compiler intrinsic in functions prototypes. The "__restrict" keyword qualifies a type as a restricted type even in C++. In case of any non-C99 languages, we don't want to match based on the restrict qualifier because we cannot know if the given libc implementation qualifies the paramter type or not. Differential Revision: https://reviews.llvm.org/D87097
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp40
1 files changed, 34 insertions, 6 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index c65d58e..2c20422 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -744,21 +744,38 @@ bool StdLibraryFunctionsChecker::evalCall(const CallEvent &Call,
bool StdLibraryFunctionsChecker::Signature::matches(
const FunctionDecl *FD) const {
assert(!isInvalid());
- // Check number of arguments:
+ // Check the number of arguments.
if (FD->param_size() != ArgTys.size())
return false;
- // Check return type.
- if (!isIrrelevant(RetTy))
- if (RetTy != FD->getReturnType().getCanonicalType())
+ // The "restrict" keyword is illegal in C++, however, many libc
+ // implementations use the "__restrict" compiler intrinsic in functions
+ // prototypes. The "__restrict" keyword qualifies a type as a restricted type
+ // even in C++.
+ // In case of any non-C99 languages, we don't want to match based on the
+ // restrict qualifier because we cannot know if the given libc implementation
+ // qualifies the paramter type or not.
+ auto RemoveRestrict = [&FD](QualType T) {
+ if (!FD->getASTContext().getLangOpts().C99)
+ T.removeLocalRestrict();
+ return T;
+ };
+
+ // Check the return type.
+ if (!isIrrelevant(RetTy)) {
+ QualType FDRetTy = RemoveRestrict(FD->getReturnType().getCanonicalType());
+ if (RetTy != FDRetTy)
return false;
+ }
- // Check argument types.
+ // Check the argument types.
for (size_t I = 0, E = ArgTys.size(); I != E; ++I) {
QualType ArgTy = ArgTys[I];
if (isIrrelevant(ArgTy))
continue;
- if (ArgTy != FD->getParamDecl(I)->getType().getCanonicalType())
+ QualType FDArgTy =
+ RemoveRestrict(FD->getParamDecl(I)->getType().getCanonicalType());
+ if (ArgTy != FDArgTy)
return false;
}
@@ -989,6 +1006,12 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
for (const Summary &S : Summaries)
operator()(Name, S);
}
+ // Add the same summary for different names with the Signature explicitly
+ // given.
+ void operator()(std::vector<StringRef> Names, Signature Sign, Summary Sum) {
+ for (StringRef Name : Names)
+ operator()(Name, Sign, Sum);
+ }
} addToFunctionSummaryMap(ACtx, FunctionSummaryMap, DisplayLoadedSummaries);
// Below are helpers functions to create the summaries.
@@ -2048,6 +2071,11 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
EvalCallAsPure)
.ArgConstraint(BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1),
/*BufSizeMultiplier=*/ArgNo(2))));
+ addToFunctionSummaryMap(
+ {"__test_restrict_param_0", "__test_restrict_param_1",
+ "__test_restrict_param_2"},
+ Signature(ArgTypes{VoidPtrRestrictTy}, RetType{VoidTy}),
+ Summary(EvalCallAsPure));
}
}