@@ -744,21 +744,38 @@ bool StdLibraryFunctionsChecker::evalCall(const CallEvent &Call,
744
744
bool StdLibraryFunctionsChecker::Signature::matches (
745
745
const FunctionDecl *FD) const {
746
746
assert (!isInvalid ());
747
- // Check number of arguments:
747
+ // Check the number of arguments.
748
748
if (FD->param_size () != ArgTys.size ())
749
749
return false ;
750
750
751
- // Check return type.
752
- if (!isIrrelevant (RetTy))
753
- if (RetTy != FD->getReturnType ().getCanonicalType ())
751
+ // The "restrict" keyword is illegal in C++, however, many libc
752
+ // implementations use the "__restrict" compiler intrinsic in functions
753
+ // prototypes. The "__restrict" keyword qualifies a type as a restricted type
754
+ // even in C++.
755
+ // In case of any non-C99 languages, we don't want to match based on the
756
+ // restrict qualifier because we cannot know if the given libc implementation
757
+ // qualifies the paramter type or not.
758
+ auto RemoveRestrict = [&FD](QualType T) {
759
+ if (!FD->getASTContext ().getLangOpts ().C99 )
760
+ T.removeLocalRestrict ();
761
+ return T;
762
+ };
763
+
764
+ // Check the return type.
765
+ if (!isIrrelevant (RetTy)) {
766
+ QualType FDRetTy = RemoveRestrict (FD->getReturnType ().getCanonicalType ());
767
+ if (RetTy != FDRetTy)
754
768
return false ;
769
+ }
755
770
756
- // Check argument types.
771
+ // Check the argument types.
757
772
for (size_t I = 0 , E = ArgTys.size (); I != E; ++I) {
758
773
QualType ArgTy = ArgTys[I];
759
774
if (isIrrelevant (ArgTy))
760
775
continue ;
761
- if (ArgTy != FD->getParamDecl (I)->getType ().getCanonicalType ())
776
+ QualType FDArgTy =
777
+ RemoveRestrict (FD->getParamDecl (I)->getType ().getCanonicalType ());
778
+ if (ArgTy != FDArgTy)
762
779
return false ;
763
780
}
764
781
@@ -989,6 +1006,12 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
989
1006
for (const Summary &S : Summaries)
990
1007
operator ()(Name, S);
991
1008
}
1009
+ // Add the same summary for different names with the Signature explicitly
1010
+ // given.
1011
+ void operator ()(std::vector<StringRef> Names, Signature Sign, Summary Sum) {
1012
+ for (StringRef Name : Names)
1013
+ operator ()(Name, Sign, Sum);
1014
+ }
992
1015
} addToFunctionSummaryMap (ACtx, FunctionSummaryMap, DisplayLoadedSummaries);
993
1016
994
1017
// Below are helpers functions to create the summaries.
@@ -2048,6 +2071,11 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
2048
2071
EvalCallAsPure)
2049
2072
.ArgConstraint (BufferSize (/* Buffer=*/ ArgNo (0 ), /* BufSize=*/ ArgNo (1 ),
2050
2073
/* BufSizeMultiplier=*/ ArgNo (2 ))));
2074
+ addToFunctionSummaryMap (
2075
+ {" __test_restrict_param_0" , " __test_restrict_param_1" ,
2076
+ " __test_restrict_param_2" },
2077
+ Signature (ArgTypes{VoidPtrRestrictTy}, RetType{VoidTy}),
2078
+ Summary (EvalCallAsPure));
2051
2079
}
2052
2080
}
2053
2081
0 commit comments