11import cpp
22
3- private string getATgMathMacroName ( boolean allowComplex ) {
3+ private string getATgMathMacroName(boolean allowComplex, int numberOfParameters ) {
44 allowComplex = true and
5+ numberOfParameters = 1 and
56 result =
67 [
78 "acos", "acosh", "asin", "asinh", "atan", "atanh", "carg", "cimag", "conj", "cos", "cosh",
8- "cproj" , "creal" , "exp" , "fabs" , "log" , "pow" , "sin" , "sinh" , "sqrt" , "tan" , "tanh"
9+ "cproj", "creal", "exp", "fabs", "log", "sin", "sinh", "sqrt", "tan", "tanh"
10+ ]
11+ or
12+ allowComplex = true and
13+ numberOfParameters = 2 and
14+ result = "pow"
15+ or
16+ allowComplex = false and
17+ numberOfParameters = 1 and
18+ result =
19+ [
20+ "cbrt", "ceil", "erf", "erfc", "exp2", "expm1", "floor", "ilogb", "lgamma", "llrint",
21+ "llround", "log10", "log1p", "log2", "logb", "lrint", "lround", "nearbyint", "rint", "round",
22+ "tgamma", "trunc",
923 ]
1024 or
1125 allowComplex = false and
26+ numberOfParameters = 2 and
1227 result =
1328 [
14- "atan2" , "cbrt" , "ceil" , "copysign" , "erf" , "erfc" , "exp2" , "expm1" , "fdim" , "floor" , "fma" ,
15- "fmax" , "fmin" , "fmod" , "frexp" , "hypot" , "ilogb" , "ldexp" , "lgamma" , "llrint" , "llround" ,
16- "log10" , "log1p" , "log2" , "logb" , "lrint" , "lround" , "nearbyint" , "nextafter" , "nexttoward" ,
17- "remainder" , "remquo" , "rint" , "round" , "scalbn" , "scalbln" , "tgamma" , "trunc" ,
29+ "atan2", "copysign", "fdim", "fmax", "fmin", "fmod", "frexp", "hypot", "ldexp", "nextafter",
30+ "nexttoward", "remainder", "scalbn", "scalbln"
1831 ]
32+ or
33+ allowComplex = false and
34+ numberOfParameters = 3 and
35+ result = ["fma", "remquo"]
1936}
2037
2138private predicate hasOutputArgument(string macroName, int index) {
@@ -27,19 +44,41 @@ private predicate hasOutputArgument(string macroName, int index) {
2744class TgMathInvocation extends MacroInvocation {
2845 Call call;
2946 boolean allowComplex;
47+ int numberOfParameters;
3048
3149 TgMathInvocation() {
32- this .getMacro ( ) .getName ( ) = getATgMathMacroName ( allowComplex ) and
50+ this.getMacro().getName() = getATgMathMacroName(allowComplex, numberOfParameters ) and
3351 call = getBestCallInExpansion(this)
3452 }
3553
54+ /** Account for extra parameters added by gcc */
55+ private int getParameterOffset() {
56+ // Gcc calls look something like: `__builtin_tgmath(cosf, cosd, cosl, arg)`, in this example
57+ // there is a parameter offset of 3, so `getOperandArgument(0)` is equivalent to
58+ // `call.getArgument(3)`.
59+ result = call.getNumberOfArguments() - numberOfParameters
60+ }
61+
3662 Expr getOperandArgument(int i) {
37- result = call .getArgument ( i ) and
38- not hasOutputArgument ( call .getTarget ( ) .getName ( ) , i )
63+ i >= 0 and
64+ result = call.getArgument(i + getParameterOffset()) and
65+ //i in [0..numberOfParameters - 1] and
66+ not hasOutputArgument(getMacro().getName(), i)
67+ }
68+
69+ /** Get all explicit conversions, except those added by clang in the macro body */
70+ Expr getExplicitlyConvertedOperandArgument(int i) {
71+ exists(Expr explicitConv |
72+ explicitConv = getOperandArgument(i).getExplicitlyConverted() and
73+ // clang explicitly casts most arguments, but not some integer arguments such as in `scalbn`.
74+ if call.getTarget().getName().matches("__tg_%") and explicitConv instanceof Conversion
75+ then result = explicitConv.(Conversion).getExpr()
76+ else result = explicitConv
77+ )
3978 }
4079
4180 int getNumberOfOperandArguments() {
42- result = call . getNumberOfArguments ( ) - count ( int i | hasOutputArgument ( getMacroName ( ) , i ) )
81+ result = numberOfParameters - count(int i | hasOutputArgument(getMacroName(), i))
4382 }
4483
4584 Expr getAnOperandArgument() { result = getOperandArgument(_) }
0 commit comments