diff options
author | Gabor Marton <gabor.marton@ericsson.com> | 2020-09-03 19:08:54 +0200 |
---|---|---|
committer | Gabor Marton <gabor.marton@ericsson.com> | 2020-09-04 11:48:38 +0200 |
commit | fe0972d3e4a65b4c5f5fa602b17ad30e463050b3 (patch) | |
tree | b6abbfefc85457fc6982bd0ce478d5eb3c803013 /clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp | |
parent | a633da5391b0e42c0185132e8b532ae9bc34489f (diff) | |
download | llvm-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.cpp | 40 |
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)); } } |